Python正则表达式匹配字符串排除字

时间:2015-07-09 12:33:31

标签: python regex

我有关于构建正则表达式的问题,我在Google,Stack Overflow和其他文档中搜索了2天...

我有以下几行:

2015-07-08 12:49:07.183852|INFO    |VirtualServerBase|  3| client disconnected 'Ròem'(id:6336) reason 'invokerid=20 invokername=Alphonse invokeruid=loremipsum2= reasonmsg=test'
2015-07-08 11:59:23.178055|INFO    |VirtualServerBase|  3| client disconnected 'Trakiyen'(id:20460) reason 'invokerid=0 invokername=server reasonmsg=idle time exceeded'
2015-07-08 12:40:50.591450|INFO    |VirtualServerBase|  3| client disconnected 'kalash'(id:20464) reason 'invokerid=136 invokername=Charles invokeruid=loremipsum= reasonmsg=Aller, Bisous! bantime=0
2015-07-08 00:23:03.235312|INFO    |VirtualServerBase|  3| client disconnected 'Brigata FTW'(id:20451) reason 'invokerid=103 invokername=Bob invokeruid=loremipsum3= reasonmsg=En vous souhaitant une bonne soirée <3 bantime=28800'

我想在这些条件下仅匹配第一行:

  1. 没有invokername=server
  2. 的行
  3. 没有bantime
  4. 的行

    在这种情况下,结果应该只匹配第一行和以下正则表达式:

    .*2015-07-08.*client disconnected.*invokername=[^server].*[^bantime=].*
    

    我只在这里写了一个正则表达式,但我已经尝试了许多不同的东西(?!等)。我已经阅读了很多关于在Stack Overflow上排除但无法找到解决方案的主题。我希望有人能帮助我。

3 个答案:

答案 0 :(得分:5)

你可以通过

获得你的路线
(?m)^(?!.*\b(?:invokername=server|bantime)\b).*2015-07-08.*client disconnected.*invokername=.*$

请参阅demo

<强>说明

  • (?m) - 一个多行标记,以便^$可以在句子的开头和结尾匹配。
  • ^ - 线锚起点
  • (?!.*\b(?:invokername=server|bantime)\b) - 一个负面的预测,确保行中没有完整的单词invokername=serverbantime
  • .*2015-07-08.*client disconnected.*invokername=.* - 包含2015-07-08client disconnectedinvokername=的子字符串,任何内容都可以在这些子字符串之间(但是换行符)。
  • $ - 行尾

或者,您可以匹配*任何没有不允许的子串的行:

(?m)^(?!.*\b(?:invokername=server|bantime)\b).*$

如果没有“超匹配”,这是一个更好的选择。

答案 1 :(得分:3)

您似乎将[^...](?!...)混淆了。前者是一个否定的角色类群,而后者是一个消极的先行者。

如果我们现在还要记住在当前位置应用负向前瞻,我们需要:

.*?2015-07-08.*?client disconnected.*?(invokername=(?!server))((?!.*?bantime=).*)

编辑:信用到期的信用:@ stribizhev&#39的解决方案比我的更好:

(?m)^(?!.*\b(?:invokername=server|bantime)\b).*$

答案 2 :(得分:2)

除了@ llogiq的答案解释了否定字符类否定预见之间的区别之外,您还可以使用negative look ahead仅使用以下正则表达式:

^((?!bantime|(?:invokername=server)).)*$

请参阅演示https://regex101.com/r/hI5dR0/1

>>> re.search(r'^((?!bantime|(invokername=server)).)*$',s,re.M).group()
"015-07-08 12:49:07.183852|INFO    |VirtualServerBase|  3| client disconnected 'R\xc3\xb2em'(id:6336) reason 'invokerid=20 invokername=Alphonse invokeruid=loremipsum2= reasonmsg=test'"