如何使用 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*
.
我想匹配 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*
.