首页 > 解决方案 > 将正则表达式限制为仅非 html 文本

问题描述

我找到了这个 javascript 函数,它替换了字符串中的所有出现。它工作得很好,但我需要它只适用于非 html 元素,这只是意味着字符串中不在“<”和“>”之间的任何部分。

String.prototype.replaceAll = function (strReplace, strWith) {
    // See http://stackoverflow.com/a/3561711/556609
    var esc = strReplace.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
    var reg = new RegExp(esc, 'ig');
    return this.replace(reg, strWith);
};

我希望这是因为有时会在 html 中找到“strReplace”字符串,因此会弄乱 HTML 输出。任何帮助表示赞赏:)

标签: javascripthtmlregex

解决方案


假设您想用replaceAll方法替换一个字符串:

  1. 如果一个字符串不是一个有效的 html,则将其视为纯文本。

  2. 如果一个字符串是一个有效的 html,则循环每个 textContent 以应用replaceAll

解决方案(使用 element.innerHTML 而不是正则表达式,正如@epascarello 所说,使用正则表达式匹配 html 不是一个好主意):

  1. 将目标字符串加载到一个 dom 元素中.innerHTML

  2. 循环此元素以获取所有文本节点。

  3. 申请replaceAll文本节点的内容。

  4. 返回el.innerHTML

String.prototype.replaceAll = function (strReplace, strWith) {
    // See http://stackoverflow.com/a/3561711/556609
    var esc = strReplace.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
    var reg = new RegExp(esc, 'ig');
    return this.replace(reg, strWith);
}

function replaceAll2 (targetString, keyword, replaceWord) {
  if (!keyword) return targetString
  let el = document.createElement('div')
  el.style.display='none'
  el.innerHTML = targetString
  let walk = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null, false)
  let next = walk.nextNode()
  while (next) {
    next.textContent = next.textContent.replaceAll(keyword, replaceWord)
    next = walk.nextNode()
  }
  return el.innerHTML
}

let test1 = 'I am a plain text'
let test2 = 'I <span>am</span> a <p>plain</p> text'
console.log(replaceAll2(test1, 'pl', '1'))
console.log(replaceAll2(test2, 'pl', '2'))


推荐阅读