正则表达式以匹配可选字符

时间:2020-09-15 13:13:40

标签: python python-3.x regex re

我正在努力寻找与以下两种格式匹配的正则表达式:

cmd1 =“ cmd:ifconfig:” PASS“:”失败“:4:2”

cmd2 =“ cmd:ifconfig:”通过“”

下面是我的示例python代码

import re
cmd_reg = r'cmd:(.*):\"(.*?)\"$'
result=re.findall(cmd_reg,cmd2)
print(result)      # output -> [('ifconfig', 'PASS')] Expectation [('ifconfig', 'PASS', 'FAIL', 4, 2)]
result=re.findall(cmd_reg,cmd1)
print(result)      # output -> [] Expectation :  [('ifconfig', 'PASS', '','','')]

但是我无法弄清楚给出期望的正则表达式

4 个答案:

答案 0 :(得分:1)

Python的regex软件包无法匹配给定组的多次出现,因此,这基本上不适用于单个正则表达式(某些其他regex实现 do 通过区分匹配项来支持此功能和捕获)。

我相信您最好的选择是

  1. 匹配整体表达式并捕获命令和其余部分,并且
  2. 使用第二个正则表达式对其余组进行迭代。
cmd_pattern = r'^cmd:([^:]+):(.*)$'
group_pattern = r'"?([^:"]+)"?' # or, simpler, r'[^:]+'; to retain quotes.

cmd, groups = re.match(cmd_pattern, cmd1).groups()
parsed_groups = re.findall(group_pattern, groups)

对于cmd2parsed_groups将是['PASS'],我认为这比您期望的结果更笼统。如果您需要用空元素填充列表,则需要手动执行。


或者,您可以对这四个组进行硬编码,并将它们设置为可选:

cmd_pattern = r'^cmd:([^:]+):([^:]+)(?::([^:]+))?(?::([^:]+))?(?::([^:]+))?'
re.match(cmd_pattern, cmd1).groups()
# ('ifconfig', '"PASS"', '"Fail"', '4', '2')

re.match(cmd_pattern, cmd2).groups()
# ('ifconfig', '"PASS"', None, None, None)

...我不建议这样做。而且,这个复杂的表达式甚至还不能处理可选的引号,这会使它变得更加复杂。

答案 1 :(得分:0)

通常,有很多方法可以实现此目的。如果您要给出其他示例,则正则表达式可以更适合一般情况(而不是过度适合此示例)。 我完全按照您的要求进行搜索,并尝试搜索:的2次之后的"的两个定界符之间的任何数字,所有这些额外的字符串都是可选的) 试试这个:

cmd1 = 'cmd:ifconfig:"PASS":"":4:'

cmd2 = 'cmd:ifconfig:"PASS"'

import re
cmd_reg = r'cmd:(.*):\"(.*)(:\"\":(\d):)?$'
result=re.findall(cmd_reg,cmd2)
print(result)
#output -> [('ifconfig', 'PASS')]
result=re.findall(cmd_reg,cmd1)
print(result)
#output -> []

输出:

[('ifconfig', 'PASS"', '', '')]
[('ifconfig:"PASS"', '":4:', '', '')]

答案 2 :(得分:0)

cmd1 = 'cmd:ifconfig:"PASS":"":4:'

cmd2 = 'cmd:ifconfig:"PASS"'

import re
cmd_reg = r'cmd:(.*):\"(.*)(:\"\":(\d):)?$'
results =re.findall(cmd_reg,str([cmd1,cmd2])
print(results)

答案 3 :(得分:0)

我建议采用以下模式:

:(\w*):"?(\w*)"?:?"?(\w*)"?:?"?(\w*)"?:?"?(\w*)"?

您可以在以下网站上以交互方式尝试上述模式:

https://regex101.com/r/M9bf6m/2