正则表达式匹配两个相同字符串之间的所有字符串

4

例如,我有这个字符串 -- This -- is -- one -- another -- comment -- 我想匹配的元素是 "This", "is", "one", "another"和"comment"

我尝试使用这个正则表达式 --\s+([^--]+)\s+-- 它给出了匹配的元素 "This", "one" 和 "comment"

我搜索了其他问题,他们都提供了像这样的解决方案,即#A# ,我将得到 A ,但对于 #A#B# 我也会得到 A ,但在这种情况下,我希望两个元素AB 都被匹配,因为它们都在两个#字符之间。

我正在测试javascript正则表达式,但我认为解决方案不应该受平台/语言的限制。


尝试使用这个正则表达式 --\s+([^--]+)\s+,然后手动删除最后两个 --:http://www.regexr.com/3fffo - Piyush Kumar Baliyan
这个 [^--]+ 将会防止在 -- mind-breaking -- 中匹配到 mind-breaking - Wiktor Stribiżew
为什么不只用 \w+? - Mustofa Rizwan
2个回答

3
一般来说,您需要使用类似以下的模式
STRING([\s\S]*?)(?=STRING|$)

它将匹配STRING,然后将任意零个或多个字符捕获到第1组中,尽可能少地捕获,在第一个出现STRING的单词之前停止,因为(?=...)是正向先行断言,是零宽度断言,不会消耗匹配的文本或字符串末尾。
一种通用的模式变化是:
STRING((?:(?!STRING)[\s\S])*)

它使用一个温和贪婪令牌(?:(?!STRING)[\s\S])*,匹配任何字符,0次或多次出现,但不以STRING字符序列开头。
要获取当前解决方案中的所有子字符串,请使用前瞻。
/--\s+([\s\S]*?)(?=\s+--)/g
                ^^^^^^^^^

请查看正则表达式演示

注意,[^--]+ 匹配除 - 以外的 1 个或多个符号,它不匹配任何与 -- 不相等的文本。 [...] 是一个字符类,用于匹配单个字符。要匹配从一个字符到模式第一次出现的任意长度文本,您可以依赖于 [\s\S]*? 结构:任何0个或多个字符,尽可能少(由于懒惰的*?量化符)。

JS 演示:

var s = '-- This -- is -- one -- another -- comment --';
var rx = /--\s+([\s\S]*?)(?=\s+--)/g;
var m, res=[];
while (m = rx.exec(s)) {
  res.push(m[1]);
}
console.log(res);


接受了答案!感谢具有正向预测的解决方案。 - Sachin G.
环视是匹配重叠子字符串的自然方法。此外,匹配任何字符的 [\s\S] 可以被本地 JS 正则表达式 [^] 构造替换(不是空),但它不具备可移植性。[\s\S] 几乎可以在任何地方使用。 - Wiktor Stribiżew
我想知道为什么你使用了/--\s+([\s\S]*?)(?=\s+--)/g而不是/--\s+([\s\S]*?)\s+(?=--)/g,这是出于性能原因还是美观原因呢? - Maciej Kozieja
@MaciejKozieja:我不认为这在这里很关键,但这很有趣。当然,\s+可以移动到前瞻之外。如果有真正的性能差异(regex101上的步骤数实际上并不能证明任何一个正则表达式比另一个更好),应该在JS环境中设置一个测试。请参见https://jsfiddle.net/pbL0cmsj/1/ - 性能几乎没有区别。 - Wiktor Stribiżew

0

要读取所有内容,我会使用正向先行断言:

const data = '-- This -- is -- one -- another -- comment --'

const readAll = data => {
  const regex =/--\s*(.*?)\s*(?=--)/g
  const found = []
  let temp
  while (temp = regex.exec(data)) {
    found.push(temp[1])
  }
  return found
}

console.log(readAll(data))

要删除注释,只需执行以下操作:

const data = `-- This -- is -- one -- another -- comment -- this is not a comment`.replace(/--.*--/g, '')

console.log(data)


请注意,OP的[^--]匹配换行符,而您的.*?则不会。 - Wiktor Stribiżew
如果您想要换行,可以使用(?:\n|.)*?,因为[^--]不允许使用一个-,因为它不是-字符的第二个破折号表示直到。 - Maciej Kozieja
Maciek,永远不要使用 (?:\n|.)*?。它会有一天崩溃你的浏览器。查看我的答案以了解使用JS正则表达式匹配任何字符的正确方法。 - Wiktor Stribiżew
所以你使用 [\s\S] 来获取包括换行符在内的所有字符,这很聪明 :D - Maciej Kozieja
在此处查看更多相关信息:链接 - Wiktor Stribiżew

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