【问题标题】:Regex: match everything but specific pattern正则表达式:匹配除特定模式之外的所有内容
【发布时间】:2010-12-13 20:14:30
【问题描述】:

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

【问题讨论】:

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

标签: regex


【解决方案1】:

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

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

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

点注:在许多风格中(但不是 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 请删除这些 cmets。你在问一个 XY 问题。字符类旨在匹配单个字符,无法用它们定义字符序列。您可能应该只找到字符串开头和cotlan 第一次出现之间的子字符串,然后删除匹配项,例如regex.replace(myString, "^.*?(?:cot|lan)\s*", "")
  • 亲爱的维克托。您已经关闭了我的问题,但是您的链接答案失败了。我已经更新了我的问题stackoverflow.com/questions/60004380/…
  • @Dotizo Python re 库与 PCRE 完全不同。使用支持(*SKIP)(*FAIL) 动词的PyPi regex library
【解决方案2】:

我需要一个能够匹配所有内容的正则​​表达式,但 except 是一个 字符串 以 index.php 开头的特定模式(特别是 index.php 以及接下来的内容,例如 index.php?id=2342343)

使用方法执行

    let match,
        arr = [],
        myRe = /([\s\S]+?)(?:index\.php\?id.+)/g;

    var str = 'http://regular-viragenia/index.php?id=2342343';

    while ((match = myRe.exec(str)) != null) {
         arr.push(match[1]);
    } 
    
    console.log(arr);

var myRe = /([\s\S]+?)(?:index\.php\?id=.+)/g;
var str = 'http://regular-viragenia/index.php?id=2342343';
var matches_array = myRe.exec(str);
console.log(matches_array[1]);

或其他匹配

let match,
            arr = [],
            myRe = /index.php\?id=((?:(?!index)[\s\S])*)/g;

        var str = 'http://regular-viragenia/index.php?id=2342343index.php?id=111index.php?id=222';

        while ((match = myRe.exec(str)) != null) {
             arr.push(match[1]);
        } 

        console.log(arr);

【讨论】:

    【解决方案3】:

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

    [^=]*
    

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

    【讨论】:

    • 没错,但它一次只处理一个字符。如果要排除两个或多个字符的序列,则必须像其他响应者所说的那样使用否定前瞻。
    • 完美的解决方案你删除任何不受欢迎的字符那些在模式。谢谢
    • @Alan, "...you have to use a negative lookahead..." 是不正确的,但我们不应该对你太苛刻,因为 Wiktor 没有发布他的答案——说明原因——直到 2016 年。
    【解决方案4】:

    不使用正则表达式如何:

    // In PHP
    0 !== strpos($string, 'index.php')
    

    【讨论】:

    • OP 专门要求使用正则表达式...我不确定这是否有帮助! (例如,他可能在命令行上使用grep,或 Perl/Python/任何其他语言,或在文本编辑器中使用“为每一行执行此正则表达式”命令等...)
    【解决方案5】:

    在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”。
    【解决方案6】:

    不是正则表达式专家,但我认为您可以从一开始就使用负前瞻,例如^(?!foo).*$ 不应匹配以 foo 开头的任何内容。

    【讨论】:

    【解决方案7】:

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

    【讨论】:

    • 也许写成str !~ /\Aindex\.php/
    猜你喜欢
    • 1970-01-01
    • 2010-10-11
    相关资源
    最近更新 更多