ChatGPT解决这个技术问题 Extra ChatGPT

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

我需要一个正则表达式,能够匹配以特定模式(特别是 index.php 和后面的内容,如 index.php?id=2342343)开头的字符串。

如果字符串匹配,您是否有理由无法匹配您的模式并且不做某事?
@ThomasOwens:这取决于。这取决于表达式的哪一部分应该被否定。如果要否定整个表达式,那么您就得到了一点。例如,如果您想编写“如果字符串不包含 'Bruce' 作为子字符串,则执行某些操作”,您可以直接使用 /Bruce/,并将否定放入 if 语句中,在正则表达式之外.但可能是你想否定一些子表达式。比如说,您正在寻找类似 firstname lastname 之类的内容,其中 firstname 是 Bruce,lastname 是除 XYZ 之外的所有内容,其中 XYZ 是某个名为 Bruce 的名人的姓氏。

W
Wiktor Stribiżew

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

以特定模式开头的字符串(例如任何 - 也为空 - 不以 foo 开头的字符串):NFA 的基于前瞻的解决方案:^(?!foo).*$ ^(?!foo)

NFA 的基于前瞻的解决方案:^(?!foo).*$ ^(?!foo)

^(?!foo).*$

^(?!foo)

针对不支持环视的正则表达式引擎的基于否定字符类的解决方案:^(([^f].{2}|.[^o].|.{2}[^o]).*|.{0,2}) $ ^([^f].{2}|.[^o].|.{2}[^o])|^.{0,2}$

^(([^f].{2}|.[^o].|.{2}[^o]).*|.{0,2})$

^([^f].{2}|.[^o].|.{2}[^o])|^.{0,2}$

以特定模式结尾的字符串(例如,没有世界。最后): 基于 Lookbehind 的解决方案:(?

基于 Lookbehind 的解决方案: (?

(?

^.*(?

前瞻解决方案: ^(?!.*world\.$).* ^(?!.*world\.$)

^(?!.*世界\.$).*

^(?!.*世界\.$)

POSIX 解决方法:^(.*([^w].{5}|.[^o].{4}|.{2}[^r].{3}|.{3}[^l].{ 2}|.{4}[^d].|.{5}[^.])|.{0,5})$ ([^w].{5}|.[^o].{4} |.{2}[^r].{3}|.{3}[^l].{2}|.{4}[^d].|.{5}[^.]$|^.{ 0,5})$

^(.*([^w].{5}|.[^o].{4}|.{2}[^r].{3}|.{3}[^l].{2}| .{4}[^d].|.{5}[^.])|.{0,5})$

([^w].{5}|.[^o].{4}|.{2}[^r].{3}|.{3}[^l].{2}|.{4} [^d].|.{5}[^.]$|^.{0,5})$

包含特定文本的字符串(例如,不匹配具有 foo 的字符串): 基于 Lookaround 的解决方案:^(?!.*foo) ^(?!.*foo).*$ POSIX 解决方法:使用 www 的在线正则表达式生成器.formauri.es/personal/pgimeno/misc/non-match-regex

基于环视的解决方案: ^(?!.*foo) ^(?!.*foo).*$

^(?!.*foo)

^(?!.*foo).*$

POSIX 解决方法:使用 www.formauri.es/personal/pgimeno/misc/non-match-regex 上的在线正则表达式生成器

使用 www.formauri.es/personal/pgimeno/misc/non-match-regex 上的在线正则表达式生成器

包含特定字符的字符串(例如,避免匹配具有 | 符号的字符串):^[^|]*$

^[^|]*$

等于某个字符串的字符串(例如,不等于 foo): 基于环视:^(?!foo$) ^(?!foo$).*$ POSIX:^(.{0,2}|.{4 ,}|[^f]..|.[^o].|..[^o])$

基于环视: ^(?!foo$) ^(?!foo$).*$

^(?!foo$)

^(?!foo$).*$

POSIX:^(.{0,2}|.{4,}|[^f]..|.[^o].|..[^o])$

^(.{0,2}|.{4,}|[^f]..|.[^o].|..[^o])$

字符序列: PCRE(匹配除 cat 之外的任何文本):/cat(*SKIP)(*FAIL)|[^c]*(?:c(?!at)[^c]*)*/i 或 / cat(*SKIP)(*FAIL)|(?:(?!cat).)+/is 其他允许环视的引擎:(cat)|[^c]*(?:c(?!at)[^c] *)* (或 (?s)(cat)|(?:(?!cat).)*, 或 (cat)|[^c]+(?:c(?!at)[^c]*) *|(?:c(?!at)[^c]*)+[^c]*) 然后用语言检查意味着:如果第1组匹配,它不是我们需要的,否则,获取匹配值如果不是空的

PCRE(匹配除 cat 之外的任何文本):/cat(*SKIP)(*FAIL)|[^c]*(?:c(?!at)[^c]*)*/i 或 /cat(*SKIP) (*失败)|(?:(?!cat).)+/是

其他允许环视的引擎: (cat)|[^c]*(?:c(?!at)[^c]*)* (或 (?s)(cat)|(?:(?!cat).) *,或 (cat)|[^c]+(?:c(?!at)[^c]*)*|(?:c(?!at)[^c]*)+[^c]* ) 然后检查语言意思是:如果第1组匹配,它不是我们需要的,否则,如果不为空,则获取匹配值

某个单个字符或一组字符:使用否定字符类:[^az]+(除小写 ASCII 字母以外的任何字符)匹配除 | 之外的任何字符:[^|]+

使用否定字符类:[^az]+(除小写 ASCII 字母以外的任何字符)

匹配任何字符,但 |: [^|]+

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

锚注:在许多语言中,使用 \A 来定义字符串的明确开头,而 \z(在 Python 中是 \Z,在 JavaScript 中,$ 可以)定义字符串的最后。

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

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


写的很棒!对于“一个字符串(不)等于某个字符串”的情况,以 ^(?!foo$) 为例,为什么美元符号必须在括号内才能使表达式起作用?我期待 ^(?!foo)$ 给出相同的结果,但事实并非如此。
@GrantHumphries:当 $ 锚点位于前瞻内时,它是条件的一部分,是 零宽度断言 的一部分。如果它在外面,就像在 ^(?!foo)$ 中一样,它将是 消费 模式的一部分,需要在字符串开始之后立即结束字符串,从而使负前瞻无关紧要,因为它总是返回 true(字符串末尾不能有任何文本,更不用说foo了)。因此,^(?!foo$) 匹配一个字符串的开头,该字符串后面不跟 foo,后面跟的是字符串结尾。 ^(?!foo)$ 匹配一个空字符串。
@robots.txt 请删除这些评论。你在问一个 XY 问题。字符类旨在匹配单个字符,无法用它们定义字符序列。您可能应该只找到字符串开头和第一次出现 cotlan 之间的子字符串,然后删除匹配项,例如 regex.replace(myString, "^.*?(?:cot|lan)\s*", "")
亲爱的维克托。您已经关闭了我的问题,但是您的链接答案失败了。我更新了我的问题stackoverflow.com/questions/60004380/…
@Dotizo Python re 库与 PCRE 完全不同。使用支持 (*SKIP)(*FAIL) 动词的 PyPi regex library
P
Peter Mortensen

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


使用 grep 使用 -P 启用前瞻。
如果不匹配“foo”或“bar”是您想要的行为,请检查以下答案:stackoverflow.com/a/2404330/874824
这个答案是错误的,快速测试表明。我认为您的意思是 ^((?!foo).)*$ (stackoverflow.com/a/406408/3964381)
F
Firsh - justifiedgrid.com

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

[^=]*

将匹配除 = 之外的所有内容


这是真的,但它一次只处理一个字符。如果要排除两个或多个字符的序列,则必须像其他响应者所说的那样使用否定前瞻。
完美的解决方案你删除除模式中的任何不受欢迎的字符。谢谢
@Alan,“......你必须使用否定的前瞻......”是不正确的,但我们不应该对你太苛刻,因为 Wiktor 直到 2016 年才发布他的答案——这说明了原因。
P
Peter Mortensen

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


也许写成str !~ /\Aindex\.php/
P
Peter Mortensen

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>

这将拒绝“index_php”或“index#php”。