非贪婪的正则表达式不符合预期

时间:2015-06-09 13:57:29

标签: python regex

给出以下字符串作为输入:

[2015/06/09 14:21:59] mod=syn|cli=192.168.1.99/49244|srv=192.168.1.100/80|subj=cli|os=Windows 7 or 8|dist=0|params=none|raw_sig=4:128+0:0:1460:8192,8:mss,nop,ws,nop,nop,sok:df,id+:0

我正在尝试匹配subj的值,即:在上述情况下,预期输出为cli

我不明白为什么我的正则表达式不起作用:

subj = re.match(r"(.*)subj=(.*?)|(.*)", line).group(2)

据我所知,这里的第二组应该是cli,但我的结果是空的。

5 个答案:

答案 0 :(得分:3)

|在正则表达式中具有特殊含义(创建alternations),因此将其转义为

>> re.match(r"(.*)subj=(.*?)\|", line).group(2)
'cli'

另一种解决方案

您可以使用re.search(),以便在subj开头和|

之后摆脱群组

示例

>>> re.search(r"subj=(.*?)\|", line).group(1)
'cli'

我们在这里使用group(1),因为只有一个正在被捕获的组而不是之前版本中的三个。

复杂版

如果使用look arounds

,您甚至可以摆脱所有捕获
>>> re.search(r"(?<=subj=).*?(?=\|)", line).group(0)
'cli'
  • (?<=subj=)检查.*?匹配的字符串是否以subj开头。

  • .*?匹配任何内容,非贪婪匹配。

  • (?=\|)检查此任何后面是|

答案 1 :(得分:2)

您需要转义| ..请使用以下内容:

subj = re.match(r"(.*)subj=(.*?)\|(.*)", line).group(2)
                                ^

答案 2 :(得分:2)

Regex101

我建议使用以下正则表达式,因为它会通过两次添加/替换提供更好的性能:

  • 添加行字符^
  • 的开头
  • 添加否定组[^\|]*(.*)?
  • 更快

<强>代码

subj = re.match(r"^.*\|subj=([^\|]*)", line).group(1)

正则表达式:

^.*\|subj=([^\|]*)

Regular expression visualization

Debuggex Demo

答案 3 :(得分:1)

管道标志<TestClass()> Public Class UnitTest1 <TestMethod()> Public Sub TestMethod1() Assert.IsTrue(True) End Sub End Class 需要转义,如下所示:

Testing started: Total tests: 1, filtered: 1 Exception: Message: An error occurred while initializing the settings provider named 'RunConfiguration'. Error: Invalid settings 'RunConfiguration'. Unexpected XmlElement: 'SolutionDirectory'. Source: Microsoft.VisualStudio.TestPlatform.Core StackTrace: at Microsoft.VisualStudio.TestPlatform.Core.RunSettings.<>c__DisplayClass2.<CreateLazyThrower>b__1() at Microsoft.VisualStudio.TestPlatform.Core.TestPluginsFramework.LazyExtension`2.get_Value() at Microsoft.VisualStudio.TestPlatform.Core.RunSettings.GetSettings(String settingsName) at CR_VSTesting.Executor.Run(ExecuteTestData data, RunSettings settings, IEnumerable`1 testCases) at CR_VSTesting.Executor.Execute(ExecuteTestData data) InnerException: Exception: Message: Invalid settings 'RunConfiguration'. Unexpected XmlElement: 'SolutionDirectory'. Source: Microsoft.VisualStudio.TestPlatform.ObjectModel StackTrace: at Microsoft.VisualStudio.TestPlatform.ObjectModel.RunConfiguration.FromXml(XmlReader reader) at Microsoft.VisualStudio.TestPlatform.Extensions.RunConfigurationSettingsProvider.Load(XmlReader reader) at Microsoft.VisualStudio.TestPlatform.Core.RunSettings.LoadSection(XmlReader reader, SettingsProviderExtensionManager settingsExtensionManager, Boolean reload) No tests found. Duration : 0.8022362

答案 4 :(得分:0)

我会使用带有[^|]*的否定类re.search来获得更好的效果:

import re
p = re.compile(r'^(.*)subj=([^|]*)\|(.*)$')
test_str = "[2015/06/09 14:21:59] mod=syn|cli=192.168.1.99/49244|srv=192.168.1.100/80|subj=cli|os=Windows 7 or 8|dist=0|params=none|raw_sig=4:128+0:0:1460:8192,8:mss,nop,ws,nop,nop,sok:df,id+:0"
print re.search(p, test_str).group(2)

请参阅IDEONE demo

注意我没有在正则表达式中使用懒惰和贪婪量词(通常不建议)。

必须对管道符号进行转义才能将其视为文字|符号。

REGEX EXPLANATION

  • ^ - 字符串开头
  • (.*) - 第一个匹配从开头到
  • 的字符的捕获组
  • subj= - 文字字符串subj=
  • ([^|]*) - 第二个捕获组匹配除文字管道之外的任何字符(在字符类中,它不需要转义)
  • \| - 文字管道(必须转义)
  • (.*) - 第三个捕获组(如果你需要在结束后获取字符串。
  • $ - 字符串结尾