【问题标题】:match all occurences of a word between 2 tags - regex匹配两个标签之间所有出现的单词 - 正则表达式
【发布时间】:2020-09-13 05:47:34
【问题描述】:

我想匹配包含在文本中 2 个标签之间的给定单词的所有实例

我的正则表达式:

(\[mytag\])(.*?)(mytext)(.*?)(\[\/mytag\])

样品1:

[mytag]1 mytext xxx -- this one should match since its withing mytag [/mytag]

样本2:

[mytag] something [/mytag]

2 mytext xxx -- THIS ONE SHOULD **NOT** MATCH - because its not actually within mytag!

[mytag] something [/mytag]

样本 3:

[mytag]4 mytext xxx -- this should match
xxxx xxx
xxxx
5 mytext -- this should match
xxx

[/mytag]

我的正则表达式适用于 Sample1。
它与 Sample2 中的 mytext 不正确匹配。它不应该匹配。
它仅匹配 Sample3 中 mytext 的第一个实例。我想匹配所有实例。

任何想法如何解决这个问题?

【问题讨论】:

  • 案例 2 工作正常 mytext 在打开关闭标签之间;对于您想要的内容,您需要向正则表达式添加条件,以便在字符串之间不包含您的标签;对于案例 3,正则表达式确实在 2 个标签之间正确找到了 1 个 mytext 也是正确的
  • 您使用什么正则表达式引擎/编程语言?它有向后看/向前看吗?

标签: regex


【解决方案1】:

如果你不想在两者之间交叉其他[mytag][/mytag],你可以使用

\[(mytag])(?:(?!\[/?\1).)*mytext(?:(?!\[/?\1).)*\[/\1

说明

  • \[匹配[
  • (mytag]) 捕获组 1,匹配 mytag]
  • (?:(?!\[/?\1).)* 匹配任何不直接跟在[ 之后的字符、可选的/ 和对第1 组的反向引用(即mytag]
  • mytext
  • (?:(?!\[/?\1).)* 再次匹配任何不直接跟随[ 的字符,可选/ 和对组1 的反向引用
  • \[/\1 匹配 [/ 和对第 1 组的反向引用

Regex demo

请注意,如果分隔符不是/,则不必转义正斜杠。

【讨论】:

    【解决方案2】:

    这是一个使用 JavaScript 的 sn-p(没有前瞻或回溯):

    // ===== test data =======================================
    
    const text=`Sample1:
    [mytag]1 mytext xxx -- this one [b]should[/b] match since its within mytag [/mytag]
    
    Sample2:
    [mytag] something [/mytag]
    
    2 mytext xxx -- THIS ONE SHOULD **NOT** MATCH - because its not actually within mytag!
    
    [mytag] something [/mytag]
    Sample3:
    
    [othertag]4 mytext xxx -- this should match
    xxxx xxx
    xxxx
    5 mytext -- this should match
    xxx
    [/othertag]`;
    
    // ===== solution starts here: ============================
    
    const regexp=/\[([a-z]+])([\w\W\n]*?)\[\/\1/gi;
    let r,matchedtext=[];
    while (r=regexp.exec(text)) matchedtext.push(r[2]);
    console.log(matchedtext.join("\n"));

    在我的正则表达式中,我捕获任何可能的标签名称并寻找匹配的对。请注意,如果存在嵌套结构,这将始终捕获 外部标记 的内容。

    第二个模式组([\w\W\n]*?) 是我在更下方的while 循环中收集的那个。它匹配任何可能以非贪婪方式出现在两个匹配标签之间的内容(包括换行符!)(?)。这样可以避免将多个标签名称相同的标签合并为一个。

    【讨论】:

      【解决方案3】:

      您可以修改现有的正则表达式以适用于任何标签.. 不仅仅是mytag。这样,您就不必检查开始和结束标记。

      \[(\w+)\](.*?)(mytext)(.*?)\[\/\1\]
      

      【讨论】:

        【解决方案4】:

        这个正则表达式将解决您的问题

        ^\s*(\[mytag\])(.*?\s*)(mytext)(.*?\s*)+(\[\/mytag\]).*
        

        现在捕获 Group3 以获得期望文本。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-10-31
          • 1970-01-01
          • 2020-07-12
          • 1970-01-01
          • 2021-12-16
          • 2010-09-22
          • 2011-10-15
          相关资源
          最近更新 更多