正则表达式:匹配除特定模式之外的所有内容

Regex: match everything but a specific pattern

提问人:pistacchio 提问时间:11/6/2009 最后编辑:Peter Mortensenpistacchio 更新时间:8/17/2023 访问量:830048

问:

我需要一个正则表达式,能够匹配除以特定模式开头的字符串之外的所有内容(具体而言,以及随后的内容,例如)。index.phpindex.php?id=2342343

正则表达式

评论

7赞 Thomas Owens 11/6/2009
如果字符串匹配,您不能与您的模式匹配并且不做某事,是否有原因?
1赞 mathheadinclouds 11/21/2019
@ThomasOwens:视情况而定。这取决于表达式的哪一部分应该被否定。如果要否定整个表达式,那么你就得到了一个点。例如,如果你想编写“如果字符串不包含'Bruce'作为子字符串,那么做点什么”,你可以简单地使用/Bruce/,并将否定放在正则表达式之外的if语句中。但可能是你想否定一些子表达式。比如说,你正在寻找类似名字姓氏的东西,其中名字是布鲁斯,姓氏是除 XYZ 之外的所有东西,其中 XYZ 是某个叫布鲁斯的名人的姓氏。

答:

3赞 user181548 11/6/2009 #1

只需匹配 ,然后拒绝任何匹配它的内容。/^index\.php/

评论

1赞 Cary Swoveland 12/18/2019
也许写过.str !~ /\Aindex\.php/
367赞 Cat Plus Plus 11/6/2009 #2

您可以从一开始就使用否定的展望,例如,不应匹配以 . 开头的任何内容。^(?!foo).*$foo

评论

9赞 Seppo Enarvi 5/31/2016
使用 grep 时,使用 -P 启用 lookahead。
2赞 dave_k_smith 8/12/2016
如果您想要的行为不匹配“foo”或“bar”,请检查以下答案: stackoverflow.com/a/2404330/874824
37赞 gilad905 6/22/2017
这个答案是错误的,快速测试表明了这一点。我想你的意思是(stackoverflow.com/a/406408/3964381^((?!foo).)*$)
3赞 AJ. 11/6/2009 #3

在 Python 中:

>>> import re
>>> p='^(?!index\.php\?[0-9]+).*$'
>>> s1='index.php?12345'
>>> re.match(p,s1)
>>> s2='index.html?12345'
>>> re.match(p,s2)
<_sre.SRE_Match object at 0xb7d65fa8>

评论

7赞 11/6/2009
这将拒绝“index_php”或“index#php”。
339赞 Firsh - justifiedgrid.com 7/20/2013 #4

您可以在字符集的开头放置 a 以匹配除这些字符之外的任何内容。^

[^=]*

将匹配所有内容,但=

评论

80赞 Alan Moore 7/20/2013
这是真的,但它一次只处理一个字符。如果要排除两个或多个字符的序列,则必须像其他响应者所说的那样使用否定前瞻。
0赞 Sirmyself 1/31/2020
完美的解决方案是删除任何不需要的字符,模式中的字符除外。谢谢
0赞 Cary Swoveland 6/8/2020
@Alan,“......你必须使用消极的展望......”是不正确的,但我们不应该对你太苛刻,因为 Wiktor 直到 2016 年才发布他的答案——这说明了原因。
0赞 padavan 5/28/2023
它如何与范围 A-z 和 _ 一起工作?[^A-z_]+ // 不起作用
0赞 Firsh - justifiedgrid.com 6/2/2023
它应该,一定是别的东西
624赞 Wiktor Stribiżew 6/23/2016 #5

正则表达式:匹配所有内容,但:

演示说明:在演示中,换行符用于否定字符类中,以避免匹配溢出到相邻行。在测试单个字符串时,它们不是必需的。\n

锚注:在许多语言中,用于定义字符串的明确开头,并且(在 Python 中,它是 ,在 JavaScript 中是可以的)定义字符串的末尾。\A\z\Z$

点注:在许多风格(但不是 POSIX、TRE、TCL)中,匹配除换行符之外的任何字符。确保使用相应的 DOTALL 修饰符(在 PCRE/Boost/.NET/Python/Java 和 Ruby 中)来匹配任何字符,包括换行符。./s/m.

反斜杠说明:在必须声明允许转义序列的 C 字符串模式的语言中(例如换行符),您需要将转义特殊字符的反斜杠加倍,以便引擎可以将它们视为文字字符(例如,在 Java 中,将被声明为 ,或使用字符类:)。使用原始字符串文字 (Python)、C# 逐字字符串文字或斜杠字符串/正则表达式表示法,如 .\nworld\."world\\.""world[.]"r'\bworld\b'@"world\."/world\./

评论

0赞 Grant Humphries 1/8/2017
写得好!对于“一个字符串(不)等于某个字符串”的情况,以 为例,为什么美元符号必须在括号内才能使表达式起作用?我期望给出相同的结果,但事实并非如此。^(?!foo$)^(?!foo)$
6赞 Wiktor Stribiżew 1/8/2017
@GrantHumphries:当锚点位于前瞻内时,它是条件的一部分,是零宽度断言的一部分。如果它在外面,就像在里面一样,它将是消费模式的一部分,要求在字符串开始之后立即结束字符串,使否定展望变得无关紧要,因为它总是返回 true(字符串末尾之后不能有任何文本,更不用说了)。因此,匹配未跟字符串的字符串的开头,然后匹配字符串末尾。 匹配空字符串。$^(?!foo)$foo^(?!foo$)foo^(?!foo)$
0赞 Wiktor Stribiżew 7/7/2019
@robots.txt 请删除这些评论。您正在问一个 XY 问题。字符类旨在匹配单个字符,无法用它们定义字符序列。您可能应该找到字符串开头和 or 第一次出现之间的子字符串,并删除匹配项,例如 regex.replace(myString, “^.*?(?:cot|lan)\s*”, “”)。cotlan
1赞 Wiktor Stribiżew 12/11/2020
@Dotizo Python 库与 PCRE 有很大不同。使用支持动词的 PyPi 正则表达式库re(*SKIP)(*FAIL)
1赞 Snailedlt 8/3/2023
鉴于问题的标题,这比公认的答案有用得多。指向 regex101 的链接也使测试和理解变得更加容易。总而言之,这是一个很棒的答案,我无疑会在未来用作参考!
-1赞 Alex Punnen 1/22/2023 #6

经过长时间的搜索,发现了这个线程。我在多次搜索和替换某些事件时遇到了这个问题。但是我使用的模式一直匹配到最后。示例如下

import re

text = "start![image]xxx(xx.png) yyy xx![image]xxx(xxx.png) end"
replaced_text = re.sub(r'!\[image\](.*)\(.*\.png\)', '*', text)
print(replaced_text)

start* end

基本上,正则表达式从第一个到最后一个匹配,吞噬中间![image].pngyyy

使用上面发布的 Firish https://stackoverflow.com/a/17761124/429476 的方法打破了事件之间的匹配。这里的空间不匹配;因为单词被空格隔开。

replaced_text = re.sub(r'!\[image\]([^ ]*)\([^ ]*\.png\)', '*', text)

并得到了我想要的

start* yyy xx* end