【问题标题】:Match everything except a specific string匹配除特定字符串之外的所有内容
【发布时间】:2017-11-30 15:44:33
【问题描述】:

我查看了很多类似标题的帖子,但我没有发现任何适用于 python 甚至这个网站的帖子:https://regex101.com

我怎样才能匹配除特定文本之外的所有内容?

我的文字:

1234_This is a text Word AB

Protocol  Address          ping
Internet  1.1.1.1            - 
Internet  1.1.1.2            25 
Internet  1.1.1.3            8 
Internet  1.1.1.4            - 

1234_This is a text Word BCD    
Protocol  Address          ping
Internet  2.2.2.1            10 
Internet  2.2.2.2            - 

我想匹配Word \w+,然后匹配其余的直到下一个 1234。 所以结果应该是(返回组标记在()):

(1234_This is a text (Word AB))(

Protocol  Address          ping
Internet  1.1.1.1            - 
Internet  1.1.1.2            25 
Internet  1.1.1.3            8 
Internet  1.1.1.4            - 

)(1234_This is a text (Word BCD)(    
Protocol  Address          ping
Internet  2.2.2.1            10 
Internet  2.2.2.2            - )

第一部分很简单:matches = re.findall(r'1234_This is a text (Word \w+)', var) 但下一部分我无法实现。 我尝试过消极的前瞻: ^(?!1234) 但随后它不再匹配...

【问题讨论】:

    标签: python regex


    【解决方案1】:

    代码

    See regex in use here

    (1234[\w ]+(Word \w+))((?:(?!1234)[\s\S])*)
    

    使用s 修饰符,您可以使用以下内容。
    See regex in use here

    (1234[\w ]+(Word \w+))((?:(?!1234).)*)
    

    说明

    • (1234[\w ]+(Word \w+)) 将以下内容捕获到捕获组 1
      • 1234 从字面上匹配这个
      • [\w ]+匹配一个或多个单词字符或空格
      • (Word \w+) 将以下内容捕获到捕获组 2
        • Word 逐字匹配(注意尾随空格)
        • \w+ 匹配任意单词字符一次或多次
    • ((?:(?!1234)[\s\S])*) 将以下内容捕获到捕获组 2
      • (?:(?!1234)[\s\S])* 匹配以下任意次数 (tempered greedy token)
        • (?!1234) 负前瞻确保后面的内容不匹配
        • [\s\S])* 匹配任意字符任意次数

    【讨论】:

    • 感谢工作。哇,这种负面的前瞻性东西仍然很难让我理解......
    • @mrCarnivore 基本上是这样说的:在字符串的这个位置,下一个字符是否匹配1234?如果是则停止匹配,否则继续匹配。
    • [\s\S] 是干什么用的?您可以将其替换为.(匹配任何字符)。但是,.* 不起作用,尽管我希望它会起作用。
    • @mrCarnivore 如果您在正则表达式中打开单行修饰符,您可以使用.. 不匹配换行符,这就是使用 [\s\S] 的原因。 [\s\S] 表示匹配任何空白或非空白字符(换句话说,匹配任何字符)。
    • @mrCarnivore 前瞻和后瞻实际上并不匹配字符来使用它们:它们基本上是断言。这意味着它将确保在 X 位置(无论 X 代表什么),确保 Y 匹配或不匹配(其中 Y 是一些条件)
    【解决方案2】:

    正如你所说:

    我想匹配 Word \w+ 然后其余的直到下一个 1234。

    你想要这样的东西吗?

    import re
    pattern=r'((1234_This is a text) (Word\s\w+))((\n?.*(?!\n\n))*)'
    string="""1234_This is a text Word AB
    
    Protocol  Address          ping
    Internet  1.1.1.1            -
    Internet  1.1.1.2            25
    Internet  1.1.1.3            8
    Internet  1.1.1.4            -
    
    1234_This is a text Word BCD
    Protocol  Address          ping
    Internet  2.2.2.1            10
    Internet  2.2.2.2            -"""
    
    match=re.finditer(pattern,string,re.M)
    for find in match:
        print("this is group_1 {}".format(find.group(1)))
        print("this is group_3 {}".format(find.group(3)))
    
    
    
    
        print("this is group_4 {}".format(find.group(4)))
    

    输出:

    this is group_1 1234_This is a text Word AB
    this is group_3 Word AB
    this is group_4 
    
    Protocol  Address          ping
    Internet  1.1.1.1            -
    Internet  1.1.1.2            25
    Internet  1.1.1.3            8
    Internet  1.1.1.4            
    this is group_1 1234_This is a text Word BCD
    this is group_3 Word BCD
    this is group_4 
    Protocol  Address          ping
    Internet  2.2.2.1            10
    Internet  2.2.2.2            -
    

    【讨论】:

    • 不,这不是我想要的结果。我希望原始文本返回并分成不同的捕获组(我在问题中标记的那些)。注意:还有一个嵌套的捕获组!
    • 谢谢。这也有效。但是,另一种解决方案更稳健一些,因为如果数据块之间没有空行,它也可以工作。
    猜你喜欢
    • 2011-01-25
    • 2013-12-22
    • 2021-03-22
    • 1970-01-01
    • 2018-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多