我知道我的问题措辞不是很好,但我无法想出另一种说法。想象一下,我有以下文字要进行正则表达式匹配:
Some random text here <STARTTAG1>text to match<ENDTAG1> some more
random text <STARTTAG2>text to match<ENDTAG2> more random text
Some random text here <STARTTAG1>I don't want this text to match<ENDTAG1> some more
random text more random text
Some random text here <STARTTAG1>text to match<ENDTAG1> some more
random text <STARTTAG2>text to match<ENDTAG2> more random text
这是我目前正在使用的正则表达式:
<STARTTAG1>(?<text1>.*?)<ENDTAG1>?.*?<STARTTAG2>(?<text2>.*?)<ENDTAG2>
如果在提供的文本上运行该正则表达式,则它与正确对中的文本不匹配。我希望它忽略任何STARTTAG1 / ENDTAG1匹配,如果他们在遇到另一个STARTTAG1 / ENDTAG1之前没有STARTTAG2 / ENDTAG2。
任何帮助将不胜感激。如果我的解释不是很好,请在文本上运行正则表达式,你就会明白我的意思(希望如此)。
谢谢!
答案 0 :(得分:2)
子模式.*?
位于:
<STARTTAG1>(?<text1>.*?)<ENDTAG1>?.*?<STARTTAG2>(?<text2>.*?)<ENDTAG2>
^ ^
here |_|
匹配应忽略的中间 TAG1
。所以我们需要匹配除<STARTTAG1>
之外的任何字符。我们可以通过一种循环来实现这一点。使用negative lookahead检查每个字符后面没有标记。
(?:(?!<STARTTAG1>).)*?
这样,它可以防止子模式与中间标记匹配。但是,由于它现在失败了,正则表达式引擎将回溯,以及之前的子模式:
(?<text1>.*?)
将尝试匹配文字:
I don't want this text to match<ENDTAG1> some more
random text more random text
Some random text here <STARTTAG1>text to match<ENDTAG1>
我们可以使用相同的方法,但我们也可以使用atomic group来阻止回溯。
(?><STARTTAG1>(?<text1>.*?)<ENDTAG1>)
<强>正则表达式强>
(?><STARTTAG1>(?<text1>.*?)<ENDTAG1>)(?:(?!<STARTTAG1>).)*?<STARTTAG2>(?<text2>.*?)<ENDTAG2>