正则表达式-如何匹配除特定模式以外的所有内容


Answers:


192

您可以使用先行断言:

(?!999)\d{3}

本示例匹配以外的三个数字999


但是,如果您碰巧没有具有此功能的正则表达式实现(请参阅“正则表达式风味比较”),则可能必须自己构建具有基本功能的正则表达式。

仅具有基本语法的兼容正则表达式为:

[0-8]\d\d|\d[0-8]\d|\d\d[0-8]

这也与不匹配的任何三个数字序列匹配999


1
前瞻性不是标准正则表达式语法,它是Perl扩展,仅适用于Perl,PCRE(与Perl兼容的RegEx)或其他非标准实现
Juliano 2009年

10
它可能不是标准的,但是大多数现代语言都不支持吗?如今,哪种语言支持预读?
Bryan Oakley,2009年

1
确实如此。但是大多数正则表达式都支持此功能(请参阅< regular-expressions.info/refflavors.html>)。
Gumbo

1
我认为最后一个正则表达式也不会匹配009、019 ...等等
Sebastian Viereck 2013年

1
C的标准Lex不使用PCRE :-(
pieman72

30

如果要匹配字符串中的单词A而不匹配单词B。例如:如果您有文本:

1. I have a two pets - dog and a cat
2. I have a pet - dog

如果要搜索的文本行中有一只狗是宠物,而没有猫,则可以使用以下正则表达式:

^(?=.*?\bdog\b)((?!cat).)*$

它只会找到第二行:

2. I have a pet - dog

他未能在问题中提及它,但OP实际上正在使用DOS findstr命令。它仅提供您期望在正则表达式工具中发现的功能的一小部分。前瞻性不在其中。(我自己刚刚添加了findstr标签。)
艾伦·摩尔

2
嗯,是的,我现在在他对帖子的评论中发现了其中之一。我在标题中看到了Regex。无论如何,如果有人像我一样在搜索正则表达式时发现了此帖子,也许对某人可能会有帮助:)感谢您的评论
Aleks

15

根据模式进行匹配,并使用宿主语言反转匹配的布尔结果。这将更加清晰和可维护。


1
然后我以(〜A或B)而不是(A和〜B)结尾。它不能解决我的问题。
notnot

1
伪代码:String toTest; if(toTest.matches(A)和!toTest.matches(B)){...}
Ben S

我应该更加清楚-这些部分不是完全独立的。如果A匹配字符串的一部分,那么我们关心〜B是否匹配其余字符串(但不一定是整个字符串)。这是针对Windows命令行findstr函数的,我发现该函数仅限于真正的正则表达式,因此尚无定论。
notnot

8

不是,请复活这个古老的问题,因为它有一个未提及的简单解决方案。(在进行正则表达式赏金任务研究时发现了您的问题。)

我面临着必须匹配(A和〜B)模式的情况。

基本的正则表达式非常简单: B|(A)

您只需忽略整体匹配并检查第一个组捕获的数据,其中将包含A。

一个示例(包含所有在正则表达式中解析html的免责声明):A是数字,B是其中的数字 <a tag

正则表达式: <a.*?<\/a>|(\d+)

演示(在右下方窗格中查看第1组)

参考

除情况s1,s2,s3之外如何匹配模式

除非...


这听起来真是太好了!不幸的是,该解决方案不是通用的,即使在替换\d为之后,也无法在Emacs中使用[[:digit:]]第一个参考文献提到它特定于Perl和PHP:“使用特定于Perl和PHP的语法的一种变体可以实现相同的功能。”
miguelmorin

4

常规语言的补充也是一种常规语言,但是要构造它,您必须为常规语言构建DFA,并将任何有效的状态更改都转化为错误。见是一个例子。页面未说的是它已转换/(ac|bd)//(a[^c]?|b[^d]?|[^ab])/。从DFA转换回正则表达式并非易事。如果像以前建议的那样,可以不变地使用正则表达式并更改代码中的语义会更容易。


2
如果我正在处理实际的正则表达式,那将是没有意义的。现在,正则表达式似乎指的是大多数语言支持的模糊的CSG式(?)模式匹配空间。由于我需要匹配(A和〜B),因此无法删除取反并仍然一步一步完成。
notnot

如上所述,如果findstr所做的事情超出了真正的DFA正则表达式,那么Lookahead就可以做到。整个过程有点奇怪,我不知道为什么我必须做这种命令行样式(现在是批处理)。这只是我的双手被绑住的另一个例子。
notnot

1
@notnot:您正在使用Windows的findstr吗?然后,您只需要/ v。像:findstr一个输入文件| FINDSTR / V B> outputfile.txt第一匹配以A的所有行,第二匹配的所有行不具有B.
Juliano的

谢谢!实际上,这正是我所需要的。不过,我没有这样问问题,因此我仍将答案提供给Gumbo,以获得更笼统的答案。
notnot

1

模式-重新

str.split(/re/g) 

将返回除模式以外的所有内容。

在这里测试


您可能想提一下,您需要再次加入。
tomdemuyt 2012年

一种类似的方法是使用replace str.replace(/re/g, ''),因此无需重新加入它们。还可以把尾随\扔进去吗?就像str.replace(/\re\s?/g, '')这样,您摆脱了在字符串中间替换
掉的内容

0

我在这里的答案也可以解决您的问题:

https://stackoverflow.com/a/27967674/543814

  • 代替替换,您将使用匹配。
  • $1您可以阅读group 而不是group $2
  • $2禁止在该群组中进行分组,您可以避免。

例:

Regex.Match("50% of 50% is 25%", "(\d+\%)|(.+?)");

第一个捕获组指定您要避免的模式。最后一个捕获组捕获其他所有内容。只需读出该组,即可$2


0
(B)|(A)

然后使用第2组捕获的内容...


他不需要捕获 B,他的目标不是仅仅忽略所有B模式。
hexicle
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.