是否有一种模式来查找字符串中多个选项中是否只有一个匹配项?
假设我们有以下潜在匹配项列表:
`foo|bar|baz`
我们有字符串:
`Foo bar, Cambaz!` // shoud not match due to multiple findings
`My bar, good!` // shoud match for `bar`
`My friend, Cambaz!` // shoud match for baz
不区分大小写。
使用
(?i)^(?:(?!foo|bar|baz).)*K(?:foo|bar|baz)(?!.*(?:foo|bar|baz))
请参阅证据。
匹配一些不匹配任何备选项的文本,直到第一个匹配项 (^(?:(?!foo|bar|baz).)*
(,省略匹配的文本 (K
(,匹配列表中的单词 ((?:foo|bar|baz)
(,然后检查文本后面的列表中没有单词 ((?!.*(?:foo|bar|baz))
(。
(?i)
- 不区分大小写。
带有子例程的缩短版本:
(?i)^(?:(?!(foo|bar|baz)).)*Kg<1>(?!.*g<1>)
查看其他证明
g<1>
代表(foo|bar|baz)
模式。
您可以使用此 PCRE 正则表达式:
^(?>.*?(foo|bar|baz)){2}.*(*SKIP)(*F)|(?1)
正则表达式演示
(*F)
或(*FAIL)
动词的行为就像一个失败的否定断言,是(?!)
的同义词(*SKIP)
定义了一个点,超过该点,当子模式稍后失败时,不允许正则表达式引擎回溯(*SKIP)(*FAIL)
技巧的想法是使用您想要避免的字符,并且这些字符不得成为匹配结果的一部分。(?1)
:递归第一个子形态
您还可以使用(*COMMIT)
在子模式之后(此处展望(失败时中止进一步的研究:
(foo|bar|baz)(*COMMIT)(?!.*(?1))
演示