我有一个很大的文本文件,由类似于以下内容的行组成:
timestamp = foo bar baz
timestamp = foo bar
timestamp = foo
我试图编写一个与foo匹配的正则表达式,但是如果同时存在bar和baz,那么它也将与它们匹配。
r"= (.*) (.*)? (.*)?"
,但仅匹配foo bar baz
字符串,不匹配其他两个。如何使正则表达式匹配可选项?
答案 0 :(得分:1)
也许这样就足够了吗?
(?<=\=\s)(\S+)\s?(\S+)? ?(\S+)?
说明:
(?<=\=\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个以上的非空白字符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', '', '')]