我有一个正则表达式问题,这是一个简化版本:
我想选择字符串中第一个匹配的值'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也应该匹配,直到下一个饼
测试输入:
馅饼乱七八糟
馅饼
馅饼朋友派朋友生气
馅饼
每个馅饼都应该匹配,除了第三个馅饼,因为它后面是朋友,但是这位朋友并没有直接跟着生气
答案 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)?
(?>...)
构造是原子组,可防止回溯。这意味着,只有在匹配所有(?!friend(?![ ]angry))
个符号后才会执行\bpie\b(?:(?!\b(?:friend|pie)\b).)*
前瞻。如果没有(?!friend(?![ ]angry))
没有直接后跟空格+ friend
,那么否定前瞻angry
将无法匹配。