如何确定是否存在可选单词

时间:2018-05-15 04:36:29

标签: python regex

我正在使用正则表达式处理一些文件,例如,如果我有以下行,我需要捕获示例编号,以及是否存在错误。

Example 1: bla bla bla
Example 2: bla bla ERROR
Example 3: bla bla

我正在'Example\s+(\d+):.*(?:ERROR)?',它会给我一个示例编号,但我怎么知道ERROR是否存在?

更新

我将非捕获组更改为捕获组,但它仍然无效。

In [77]: line = 'Example 5: abv ERROR zyx'

In [78]: re.search('Example\s+(\d+).+(ERROR)?', line).group(2)

In [79]: re.search('Example\s+(\d+).+(ERROR)', line).group(2)
Out[79]: 'ERROR'

我很困惑,这个词就在那里,但是为什么可选的捕获组没有捕获它?

2 个答案:

答案 0 :(得分:0)

如果ERROR始终位于该行的末尾,您可以执行以下操作:

  • 将非捕获组(?:ERROR)转换为捕获组。
  • 使用惰性匹配.*替换.*?的贪婪匹配。
  • 在末尾添加行尾断言$

所以,你的正则表达式看起来像这样:

Example\s+(\d+):.*?(ERROR)?$

Try it online

然后,您可以检查第二组是否为空。

如果Error不必在行的末尾,您可以调整上面的正则表达式,如下所示:

Example\s+(\d+):(?:.*?(ERROR)|.*)

正则表达式的这部分(?:.*?(ERROR)|.*)的工作原理如下:

(?:       # This is the start of a non-capturing group.
.*?       # Lazy match for zero or more characters (same as the above solution).
(ERROR)   # Matches the characters `ERROR` literally, placed in a capturing group to be able to check if empty (same as the above solution).
|         # Alternative. Meaning match either what's before the `|` or what's after it _inside the non-capturing group_.
.*        # Greedy match for zero or more characters (same as you first original regex).

所以,这基本上会查找任意数量的字符(懒惰),然后是ERROR 任意数量的字符(贪婪)后面没有ERROR < / em>的

Here's a demo

希望有所帮助。

答案 1 :(得分:-1)

你想做什么?您当前的解决方案应该稍作修改:

re.findall(r'^Example\s+(\d+):|(ERROR)', line)

如果返回的数组长度为2则表示找到ERROR。

如果存在ERROR,请执行以下示例:

>>> line = 'Example 5: abv ERROR zyx'
>>> re.findall(r'^Example\s+(\d+):|(ERROR)', line)
[('5', ''), ('', 'ERROR')]

如果ERROR不存在,请执行以下示例:

>>> line = 'Example 5: abv zyx'
>>> re.findall(r'^Example\s+(\d+):|(ERROR)', line)
[('5', '')]