我有以下伪DSL:
< allow | deny >
< tcp | udp | any >
src < prefix | $ip | @hostgroup | any > [ port number | range | @portgroup | any ]
dst < prefix | $ip | @hostgroup | any > [ port number | range | @portgroup | any ]
[ stateful ]
[ expire YYYYMMDD ] [ log ]
[ # comment ]
订单已修复,从允许最多dst
及其port
开始。
我与以下相匹配,相当愚蠢,正则表达式:
m = re.search("^(allow|deny)?\s+(tcp|udp|tcpudp|any)\s+?(src\s\S+)\s*?(port\s+\S+)?\s*?(dst\s\S+)\s?(port\s+\S+)?\s*?(\S+)?\s*?(\S+)?", line)
请原谅我提出的问题,但我遇到问题的部分是:
stateful
,expire <value>
,log
,但如果它们存在,我想在不同的组中匹配它们。port <value>
,使匹配组仅包含值,而不创建额外匹配组,即不使用(port\s+(\S+))?
谢谢!
[编辑更多问题陈述]
为了详细说明,我确定可以检查3个组中的一个是否包含log
或stateful
,但是如果我使用相同的方法,则非过期的非捕获组,又名(?:expire\s(\S+))
,我需要做出一个假设。除非我能以某种方式进行无顺序匹配?即匹配(stateful|log|(?:expire\s(\S+)))
?
答案 0 :(得分:2)
- 如果所有3个都是可选的,我如何匹配
醇>stateful
,expire <value>
,log
,但如果它们存在,我想在不同的组中匹配它们。
使用后面有?
的捕获组,以便它们可选。
实施例。 \s*(stateful)?\s*(?:expire (\d{8}))?\s*(log)?
要允许这些可选组以匹配字符串中的任何顺序显示,但仍然始终将它们放在同一编号的捕获组中,请使用前瞻(?= )
。
实施例。 (?=(?:.*(stateful))?)(?=(?:.*expire (\d{8}))?)(?=(?:.*(log))?)
- 如何匹配可选语句
醇>port <value>
,使匹配组仅包含值,而不创建额外的匹配组,即不使用
(port\s+(\S+))?
使用非捕获组(?: )
将这些字符放在一起用于以下?
而不捕获它们。 (你可能也希望在上面expire
执行此操作)
(?:port\s+(\s+))?