javascript - 替换和正则表达式异常
问题描述
我想将文本的所有单词包装在<trans>
标签中,以便能够处理每个单词。将它们悬停,点击翻译等。
为此,我需要在我的替换函数中有一个例外来忽略 html 标签,如<br>
or <span>
。
这是我的功能:
function wrapWords(str, tmpl) {
return str.replace(/(?![<br>\<span class="gras">\</span>])[a-zA-ZÀ-ÿ]+/gi, tmpl || "<trans>$&</trans>");
}
此功能适用于俄语字符,但不适用于法语字符。问题是<br>
and<span>
异常不包括法语字符 b,r,s,p,a... 因为有些单词没有正确包装在我的<trans>
标签中。
有谁知道我如何排除一组字符(例如特定标签<br>
)而不影响法语中的字母 b 和 r ?
感谢您的任何回答!
解决方案
正确使用 DOM 会稍微复杂一些,但无需担心极端情况,因为它非常简单。
您想要拆分文本,因此只对文本节点进行操作是有意义的。要查找所有文本节点,我们可以评估一个 XPath,或者我们可以构造一个TreeWalker
.
一旦我们知道我们想要在哪些节点上进行操作,我们一次取一个节点并获得全空间和非空间序列。每个都将转换为另一个文本节点,但无空格序列将另外包装在一个<span>
. 我们将它们一一附加在原始节点的前面,这将保证正确的顺序,最后我们将删除原始节点,当替换节点都在它们的位置时。
function getTextNodes(node) {
let walker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT, null, false);
let textnodes = [];
let textnode;
while (textnode = walker.nextNode()) {
textnodes.push(textnode);
}
return textnodes;
}
function wrap(element) {
getTextNodes(element).forEach(node => {
node.textContent.replace(/(\S+)|(\s+)/g, (match, word, space) => {
let textnode = document.createTextNode(match);
let newnode;
if (word) {
newnode = document.createElement('trans');
newnode.appendChild(textnode);
} else {
newnode = textnode;
}
node.parentNode.insertBefore(newnode, node);
});
node.remove();
});
}
wrap(document.getElementById('wrapthis'));
trans {
background-color: pink;
}
Not affected<br/>
<div id="wrapthis">
This is affected<br>
<span class="gras">HTML tags are fine</span><br/>
This as well<br/>
</div>
Not affected<br/>
推荐阅读
- html - 无法从打字稿文件中获取 img url
- rest - 对 Azure AD 进行非交互式身份验证,以在 Sharepoint Project Server 上进行 CRUD 操作
- azure-devops - 本地机器上的 VSTS 构建代理不提供代码覆盖率数据
- android - 无法在 Appium 的任一屏幕中定位任何元素
- hyperledger-fabric - 错误:尝试 ping 时出错。错误:Composer 运行时 (0.19.4) 与客户端 (0.20.0) 不兼容
- instagram - Instagram API - 影响者可以在我的平台上显示见解吗?
- tomcat - 在同一台机器上的 Tomcat8 和 Tomcat9 上安装 Jenkins
- ansible - 如何在库存文件中添加服务器路径 - ansible
- jquery-ui - 没有当前日期的jQuery-UI日期选择器?
- java - 良好实践:API 和 MVC - 我应该将方法/函数与 API 的 SQL 查询放在哪里