正则表达式 - 如果首先跟随完全字符串本身就是一个直接跟随字符串,则需要匹配字符串

时间:2016-01-13 23:51:16

标签: .net regex

我有一个正则表达式问题,这是一个简化版本:

我想选择字符串中第一个匹配的值'pie'是'friend',它不会被字符串'angry'直接跟随。

这是我得到的:

正则表达式

\b(pie)\b(?!(.|\n|\r|\r\n)*?friend[ ]angry)

它一直到'朋友生气'的最后一场比赛,但我想在第一个'朋友'之后停止处理,并检查它是否直接跟着'生气'

字符串:

pie jibberish jibberish friend pie friend pie jibberish friend angry pie friend

我有一个正则表达式几乎可以做我想要的,但是一个停在一个字符,而不是一个字符串:

\b(pie)\b(?![^<]*([<]/h\d)) 这个检查字符串是否直接包含在h2标记中,但我想匹配字符串,而不是字符

我的正则表达式真的很生疏,我认为这应该是可能的......

链接到regextest

更新

正则表达式应匹配pie。如果在匹配后找到字符串“friend angry”,则匹配的值不应匹配,但如果找到朋友则匹配。 如果在下面的字符串中找不到朋友,那么Pie也应该匹配,直到下一个饼

测试输入:
馅饼乱七八糟 馅饼
馅饼朋友派朋友生气
馅饼

每个馅饼都应该匹配,除了第三个馅饼,因为它后面是朋友,但是这位朋友并没有直接跟着生气

1 个答案:

答案 0 :(得分:1)

我假设您已经从HTML代码解析了字符串,而您正在使用纯文本。

要匹配两个字符串之间的最短窗口是一个驯化的贪婪令牌(可以展开)。

(?s)\bpie\b(?:(?!\b(?:friend|pie)\b).)*friend[ ]angry
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^

请参阅regex demo

(?:(?!\bfriend\b).)*子模式匹配任何未启动(?s)friend字符序列的符号(请注意内嵌单行修饰符pie,使点匹配换行符)

请注意,[ ]可以替换为\p{Zs},以匹配所有水平 Unicode空白字符。

为了避免匹配pie没有直接跟随的friend,您需要在之后使用否定前瞻消耗pie之后的所有字符在friend angry

之前
(?s)(?>\bpie\b(?:(?!\b(?:friend|pie)\b).)*)(?!friend(?![ ]angry))(?:friend[ ]angry)?

请参阅this regex demo

(?>...)构造是原子组,可防止回溯。这意味着,只有在匹配所有(?!friend(?![ ]angry))个符号后才会执行\bpie\b(?:(?!\b(?:friend|pie)\b).)*前瞻。如果没有(?!friend(?![ ]angry))没有直接后跟空格+ friend,那么否定前瞻angry将无法匹配。