有没有一种方法可以在包含换行符(\n)的字符串中搜索子字符串?

3

我有一段文本,其中包含\n符号,我有一个短语数组想要用<mark>标签将其在文本中的片段高亮显示。问题是,如果文本中存在\n符号,我就无法找到这些短语。

我尝试从文本中替换\n符号,但我需要在高亮显示后还原它们。

let text = 'Looking For An Enterprise Test Authoring Platform?\n
Learn More About Gauge\n
Watch our video to learn if Gauge can help you.'

let phrases = ["Authoring Platform? Learn More", "Gauge Watch our video", "can help you"]

const highlight = (phrase) => text.replace(phrase, `<mark style="background: #4CAF50">${phrase}</mark>`)

phrases.map(phrase=> text = highlight(phrase))

只有最后一句话与文本匹配。我正在寻找一种方法来忽略 \n 并匹配所有这些短语。或者也许有其他解决方法。感谢任何帮助!


如果换行符只能出现在单词之间,那么您可以相当容易地编写实际的正则表达式来允许它们之间存在换行符。结合捕获匹配,以便您可以在替换后使用它。 - misorude
但是你现有的代码无法处理多个重叠的替换 - 如果你曾经需要替换“mark”或“style”这样的“短语”,那么它会混淆你已经完成的任何先前的替换。 - misorude
3个回答

1

一种选择是循环遍历短语并创建动态正则表达式。将每个\s替换为(?:\n)*。这将创建一个像这样的动态正则表达式:

/Authoring(?:\n)* Platform\?(?:\n)* Learn(?:\n)* More/

然后使用$&将匹配的子字符串替换为text。这样可以保留原始字符串中的\n

let text = 'Looking For An Enterprise Test Authoring Platform?\n Learn More About Gauge\n Watch our video to learn if Gauge can help you.'

let phrases = ["Authoring Platform? Learn More", "Gauge Watch our video", "can help you"]

// https://dev59.com/rnRB5IYBdhLWcg3w1Kr0#494122
const escape = str => str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1")

phrases.forEach(p => {
  const regex = new RegExp( escape(p).replace(/\s/g, '\(?:\n)* ') )
  text = text.replace(regex, `<mark style="background:#4CAF50">$&</mark>`)
})

console.log(text)

escape 函数取自 这里。它用于从每个短语中转义元字符,如 ?

这是一种使用 reduce 和一些辅助函数的替代方案:

const text = 'Looking For An Enterprise Test Authoring Platform?\n Learn More About Gauge\n Watch our video to learn if Gauge can help you.',
      phrases = ["Authoring Platform? Learn More", "Gauge Watch our video", "can help you"],
      escape = str => str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"),
      createReg = p => new RegExp( escape(p).replace(/\s/g, '\(?:\n)* ') ),
      replaceWith = '<mark style="background:#4CAF50">$&</mark>',
      output = phrases.reduce((a, p) => a.replace(createReg(p), replaceWith), text)

console.log(output)


0

你可以通过取第一个单词并将你的句子与这个简单的正则表达式匹配来绕开,\b第一个单词 (.*?) 结束单词\b

let text = 'Looking For An Enterprise Test Authoring Platform?\n
            Learn More About Gauge\n
            Watch our video to learn ifGauge can help you.';

 text.match(/\Gauge (.*?) video\b/gis)
 // ["Gauge↵↵Watch our video"]
 // \n character is being preserved

这可能会使它变得更加复杂,因为您需要找到每个句子的第一个和最后一个单词。


如果没有重复的单词,似乎它正在工作。 - Angelina Ratnykova
@AngelinaRatnykova,你能给我一个例子吗?我会看看能否绕过那个问题。 - NickHTTPS

-1

只需从字符串中删除 \n 并像这样检查该字符串中的短语。

let text = 'Looking For An Enterprise Test Authoring Platform?\n
Learn More About Gauge\n
Watch our video to learn ifGauge can help you.';

let phrases = ["Authoring Platform? Learn More", "Gauge Watch our video", "can help you"];

//string without \n
let plainText = text.replace("\n", "");

const highlight = (phrase) => {
    return plainText.replace(phrase, `<mark style="background: #4CAF50">${phrase}</mark>`)
}


phrases.map(phrase=> {
    text = highlight(phrase)
})  

2
我尝试过从文本中替换掉换行符,但是在高亮之后我需要恢复它们 - David Thomas
懒惰的解决方案:首先保存 \n 的索引(位置)-> 从字符串中删除它们 -> 替换子字符串 -> 在第一步中存储的位置重新添加 \n 到字符串。 - Adams Hales
1
@AdamsHales 在将短语包围后,\n所需放置的位置会发生变化。 - user10928257

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接