正则表达式匹配随机顺序单词

时间:2016-05-25 21:33:16

标签: python regex

我有以下伪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)

请原谅我提出的问题,但我遇到问题的部分是:

  1. 如果所有3个都是可选的,我如何匹配statefulexpire <value>log,但如果它们存在,我想在不同的组中匹配它们。
  2. 如何匹配可选语句port <value>,使匹配组仅包含值,而不创建额外匹配组,即不使用(port\s+(\S+))?
  3. 谢谢!

    [编辑更多问题陈述]

    为了详细说明,我确定可以检查3个组中的一个是否包含logstateful,但是如果我使用相同的方法,则非过期的非捕获组,又名(?:expire\s(\S+)),我需要做出一个假设。除非我能以某种方式进行无顺序匹配?即匹配(stateful|log|(?:expire\s(\S+)))

1 个答案:

答案 0 :(得分:2)

  
      
  1. 如果所有3个都是可选的,我如何匹配statefulexpire <value>log,但如果它们存在,我想在不同的组中匹配它们。
  2.   

使用后面有?的捕获组,以便它们可选。

实施例。 \s*(stateful)?\s*(?:expire (\d{8}))?\s*(log)?

要允许这些可选组以匹配字符串中的任何顺序显示,但仍然始终将它们放在同一编号的捕获组中,请使用前瞻(?= )

实施例。 (?=(?:.*(stateful))?)(?=(?:.*expire (\d{8}))?)(?=(?:.*(log))?)

  
      
  1. 如何匹配可选语句port <value>,使匹配组仅包含值,而不创建额外的匹配组,即不使用
      (port\s+(\S+))?
  2.   

使用非捕获组(?: )将这些字符放在一起用于以下?而不捕获它们。 (你可能也希望在上面expire执行此操作)

(?:port\s+(\s+))?

Complete Regex