Regex 如何否定正则表达式中的特定单词?
我知道我可以像在Regex 如何否定正则表达式中的特定单词?,regex,Regex,我知道我可以像在[^bar]中那样否定一组字符,但我需要一个正则表达式,其中否定适用于特定的单词-因此在我的示例中,我如何否定一个实际的,而不是“bar中的任何字符”您可以使用: 这些都匹配任何不包含bar的内容,除非性能是最重要的考虑因素,否则只需在第二遍中运行结果通常会更容易,跳过那些与要否定的词匹配的内容 正则表达式通常意味着您正在编写脚本或执行某种低性能任务,因此,请找到一种易于阅读、易于理解和维护的解决方案。以下正则表达式将满足您的需要(只要支持负lookbehinds和lookahe
[^bar]
中那样否定一组字符,但我需要一个正则表达式,其中否定适用于特定的单词-因此在我的示例中,我如何否定一个实际的,而不是“bar中的任何字符”您可以使用:
这些都匹配任何不包含bar
的内容,除非性能是最重要的考虑因素,否则只需在第二遍中运行结果通常会更容易,跳过那些与要否定的词匹配的内容
正则表达式通常意味着您正在编写脚本或执行某种低性能任务,因此,请找到一种易于阅读、易于理解和维护的解决方案。以下正则表达式将满足您的需要(只要支持负lookbehinds和lookaheads),并正确匹配;唯一的问题是它匹配单个字符(即,每个匹配都是单个字符,而不是两个连续“条”之间的所有字符),如果使用很长的字符串,可能会导致高开销
b(?!ar)|(?<!b)a|a(?!r)|(?<!ba)r|[^bar]
b(?!ar)|(?一个很好的方法是使用:
负先行结构是一对括号,左括号后跟问号和感叹号
我只是想到了一些可以做的事情。这与我的第一个答案非常不同,因为它不使用正则表达式,所以我决定写第二个答案
在字符串上使用所选语言的split()
等效方法,并将单词to negate作为拆分内容的参数。使用Python的示例:
>>> text = 'barbarasdbarbar 1234egb ar bar32 sdfbaraadf'
>>> text.split('bar')
['', '', 'asd', '', ' 1234egb ar ', '32 sdf', 'aadf']
这样做的好处是,至少在Python中(我不记得在Visual Basic或Java中的功能是否相同),它让您间接知道字符串中何时重复“bar”,因为“bar”之间的空字符串包含在结果列表中(虽然开头的空字符串是因为字符串开头有一个“bar”)。如果你不想这样做,你可以简单地从列表中删除空字符串。我在尝试识别以下英语语句的正则表达式时遇到了这个论坛线程:
给定一个输入字符串,匹配所有内容,除非该输入字符串正好是“bar”;例如,我想匹配“barrier”和“disbar”以及“foo”
这是我想出的正则表达式
^(bar.+|(?!bar).*)$
我对正则表达式的英文翻译是“如果字符串以'bar'开头并且至少有一个其他字符,或者字符串不以'bar'开头,则匹配字符串”。我有一个文件名列表,我想排除某些文件名,这种行为(Ruby):
以下是我的解决方案:
excluded_rgx = excluded.map{|e| e+'\.'}.join('|')
my_rgx = /(^|\/)((?!#{excluded_rgx})[^\.\/]*)\.rb$/
我对此应用程序的假设:
- 要排除的字符串位于输入的开头,或紧跟在斜杠之后
- 允许的字符串以
.rb
结尾
- 允许的文件名在
.rb
前面没有
字符
接受的答案很好,但实际上是解决正则表达式中缺少简单的子表达式求反运算符的问题。这就是为什么存在
grep--inverse match
的原因。因此,在*nixes中,您可以使用管道和第二个正则表达式实现所需的结果
grep 'something I want' | grep --invert-match 'but not these ones'
仍然是一个解决方法,但可能更容易记住。解决方案:
^(?!.*STRING1|.*STRING2|.*STRING3).*$
xxxxxx正常
xxxSTRING1xxxKO(是否需要)
xxxSTRING2xxxKO(是否需要)
xxxSTRING3xxxKO(是否需要)我希望补充已接受的答案,并用我迟交的答案为讨论做出贡献
@ChrisVanOpstal共享,这是学习正则表达式的一个很好的资源
然而,通读起来确实很费时
为了便于记忆,我做了一张备忘单
这个参考是基于每个类前面的大括号[]
,()
和{}
,我发现很容易回忆起来
Regex = {
'single_character': ['[]', '.', {'negate':'^'}],
'capturing_group' : ['()', '|', '\\', 'backreferences and named group'],
'repetition' : ['{}', '*', '+', '?', 'greedy v.s. lazy'],
'anchor' : ['^', '\b', '$'],
'non_printable' : ['\n', '\t', '\r', '\f', '\v'],
'shorthand' : ['\d', '\w', '\s'],
}
摘自:
此解决方案的优点是可以明确否定(排除)多个单词:
^(?!bar$|foo$|banana$).*
如果它确实是一个你不想匹配的单词,bar
,那么:
^(?!.*\bbar\b).*$
以上内容将匹配任何不包含位于单词边界上的条
,即与非单词字符分开的字符串。但是,除非使用正确的正则表达式标志,否则上述模式中使用的句点(
)将不匹配换行符:
^(?s)(?!.*\bbar\b).*$
或者:
^(?!.*\bbar\b)[\s\S]*$
我们不使用任何特殊标志,而是寻找任何空白或非空白字符。这应该涵盖所有字符
但是,如果我们想匹配可能包含bar
,但不包含特定单词bar
,该怎么办
(?!\bbar\b)\b\[A-Za-z-]*bar[a-z-]*\b
(?!\bbar\b)
断言下一个输入不是单词边界上的条
\b\[A-Za-z-]*条[A-z-]*\b
匹配包含条的单词边界上的任何单词
什么语言不支持regex中的(负面)look behinds和/或(负面)look aheads?我想提出的要点是,从你的模式来看,根本不清楚你所做的只是拒绝“bar”一词。@Bryan:事实上,它并不拒绝“bar”一词。它只是拒绝“b”后接“ar”“。好主意,但并非所有地方都支持。Afaik Javascript支持负向前瞻,但不支持向后看。我不知道有关其他语言的详细信息,但这可能会有所帮助:@JAB bash不支持负向前瞻/向前看。这说明了一切(我可能从(?!bar)开始并建立).我不明白为什么其他人把事情弄得这么复杂
^(?!bar$|foo$|banana$).*
^(?!.*\bbar\b).*$
^(?s)(?!.*\bbar\b).*$
^(?!.*\bbar\b)[\s\S]*$
(?!\bbar\b)\b\[A-Za-z-]*bar[a-z-]*\b