替换和正则表达式例外

时间:2018-11-21 06:06:34

标签: javascript regex replace

我想将文本的所有单词都包装在<trans>标记中,以便能够处理每个单词。悬停它们,点击翻译等。

为此,我需要在我的replace函数中设置一个异常,以忽略诸如<br><span>之类的html标签。

这是我的功能:

function wrapWords(str, tmpl) {
  return str.replace(/(?![<br>\<span class="gras">\</span>])[a-zA-ZÀ-ÿ]+/gi, tmpl || "<trans>$&</trans>");
}

此功能与俄语字符兼容,但与法语字符兼容。问题是<br><span>例外排除了法语字符b,r,s,p,a ...因此,某些单词未正确包装在我的<trans>标记中

有人知道如何在不影响法文字母b和r的情况下排除例如特定标签<br>之类的字符吗?

谢谢您的回答!

2 个答案:

答案 0 :(得分:2)

正确使用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/>

答案 1 :(得分:1)

这是一种快速的方法:

"foo bar baz".split(" ").map(w => "<trans>" + w + "</trans>").join(" ");

说明:

句子由空格字符分隔,从而得到Array。然后,将此Array的每个元素包装在<trans>标记中。然后将所有内容连接起来以创建一个字符串。

编辑:在DOM中的用法:

var sourceTextNode = document.createElement("div"); // here you're supposed to get an existing node...
sourceTextNode.textContent = "foo bar baz"; // ... and doing this is for the example purposes

sourceTextNode.innerHTML = sourceTextNode.textContent.split(" ").map(w => "<trans>" + w + "</trans>").join(" ");

sourceTextNode是:

<div>
  <trans>foo</trans>
  <trans>bar</trans>
  <trans>baz</trans>
</div>

注意:您可能希望在拆分数组中排除多个连续的空格字符时会得到的空元素。 一种方法是测试过滤器中元素的非空性:

sourceText.split(" ").filter(Boolean)...