有条件地匹配多个单词

时间:2019-09-22 23:51:44

标签: python regex

我有一个很大的文本文件,由类似于以下内容的行组成:

timestamp = foo bar baz
timestamp = foo bar
timestamp = foo

我试图编写一个与foo匹配的正则表达式,但是如果同时存在bar和baz,那么它也将与它们匹配。

r"= (.*) (.*)? (.*)?"

,但仅匹配foo bar baz字符串,不匹配其他两个。如何使正则表达式匹配可选项?

3 个答案:

答案 0 :(得分:1)

也许这样就足够了吗?

 (?<=\=\s)(\S+)\s?(\S+)? ?(\S+)?

Regex Demo

说明:

 (?<=\=\s)       # Positive lookbehind - capture = + space but don't match
 (\S+)           # Capture any non-whitespace character
 \s?             # Capture optional space
 (\S+)?          # Capture any non-whitespace character
  ?              # Capture optional space
 (\S+)?          # Capture any non-whitespace character

答案 1 :(得分:1)

我猜测您可能可以使用一些简单的表达式来获得所需的输出,例如:

(\w+\s*=\s*)|(\w+)

测试

import re


regex = r"(\w+\s*=\s*)|(\w+)"
string = """
timestamp = foo bar baz foo bar baz
timestamp = foo bar baz
timestamp = foo bar
timestamp = foo
"""

for groups in re.findall(regex, string):
    if groups[0] == '':
        print(groups[1])
    else:
        print("--- next timestamp ----")

输出

--- next timestamp ----
foo
bar
baz
foo
bar
baz
--- next timestamp ----
foo
bar
baz
--- next timestamp ----
foo
bar
--- next timestamp ----
foo

如果您希望简化/修改/探索表达式,请在regex101.com的右上角进行说明。如果愿意,您还可以在this link中查看它如何与某些示例输入匹配。


答案 2 :(得分:0)

您可以使用

r'= *(\S+)(?: *(\S+))?(?: *(\S+))?'

或者,为了匹配任何水平空白:

r'=[^\S\r\n]*(\S+)(?:[^\S\r\n]*(\S+))?(?:[^\S\r\n]*(\S+))?'

请参见regex demo

详细信息

  • =[^\S\r\n]*-一个=字符,除LF,CR和非空格(即换行和回车符以外的所有空格)以外的任何0个或多个字符,或者您使用 *
  • (\S+)-第1组:任意1个以上的非空白字符
  • (?:[^\S\r\n]*(\S+))?-与1个或0个匹配项匹配的可选非捕获组
    • [^\S\r\n]*-0+个水平空格
    • (\S+)-第2组:任意1个以上的非空白字符
  • (?:[^\S\r\n]*(\S+))?-与1个或0个匹配项匹配的可选非捕获组
    • [^\S\r\n]*-0+个水平空格
    • (\S+)-第3组:任意1个以上的非空白字符

Python demo

import re
s = "timestamp = foo bar baz\ntimestamp = foo bar\ntimestamp = foo"
print( re.findall(r'= *(\S+)(?: *(\S+))?(?: *(\S+))?', s) )
# => [('foo', 'bar', 'baz'), ('foo', 'bar', ''), ('foo', '', '')]