如何使用 python re.findall 在正则表达式中匹配值 none 或一次

how to match a value none or one time in regex using python re.findall

我想匹配 java -c 123.java 或 java 123.java 这样的模式。 看到 -c 是可选的,它可以来一次或 none。 到目前为止我正在使用

java\s+-c\s+[\d]+\.java|java\s+[\d]+\.java

工作正常 请不要检查命令有效性,这是一个示例。 我更喜欢这种方式而不是使用像

这样的管道符号
java\s+(-c){0,1}\s+[\d]+\.java

但是当我使用 re.findall 时,它返回空字符串,但与 re.search 一起工作正常。由于 re.findall 对我来说是强制性的,像 (-c) 这样的分组是否正确,或者您能否建议对上述正则表达式进行任何更改?

代码:

seq="java -c 123.java"
pattern="java\s+(-c){0,1}\s+[\d]+\.java"
pattern=re.compile(pattern)
pattern.findall(seq)

输出:['-c'] 我想得到 java -c 123.java 正如@9769953 指出的那样,如果 seq="java 123.java",输出是空列表,如果 seq="java 123.java" #注意额外的空格,输出是 ['']。 @mozway 我用

的时候试过你说的
java\s+(-c)?\s+[\d]+\.java

它正在返回 ['-c'] 我做错了什么?

据我了解,你想用re.findall找到java <possible option flag> option-value的整个模式,同时还保留使用re.search的可能性(后者只会找到第一个出现,如果有的话)。

我假设这意味着输入可以是

text = "blah blah java -c 123.java blah blah java 123.java"

并且您想找到这两个事件。

re.findall 捕获文本字符串中的 groups。因此,您需要对相关模式进行分组,在本例中为完整模式。为避免同时捕获可选的 -c,您需要将此组设为 non-capturing.

普通组用括号括起来; non-capturing 组将以 (?: 开始并以正常对应的结束 ).

结束

如果 -c 不存在(而不是 \s+\s+ 的两个匹配项,则允许使用单个空格,这将导致至少需要两个空格字符)[1],并且通过使用 ? 进行可选匹配的简化,模式将是:

pattern = r"(java\s+(?:-c\s+)?[\d]+\.java)"

这也使用了原始字符串(通过使用 r 前缀),这避免了将一些黑斜杠字符解释为特殊的东西,这在正则表达式中通常不是人们想要的。

使用上面的输入文本和模式,现在的结果是:

>>> regex = re.compile(pattern)
>>> regex.findall(text)
['java -c 123.java', 'java 123.java']
>>> regex.search(text)
<re.Match object; span=(10, 26), match='java -c 123.java'>
>>> regex.search(text).group(1)
'java -c 123.java'

[1] 此模式不捕获 java -c123.java,简称(即 one-letter)选项通常是标准的。如果您还想捕获这种可能性,请将第二个 \s+ 更改为 \s*.