正则表达式匹配列表,禁止尾随逗号

时间:2014-07-11 17:00:40

标签: php regex

我正在构建验证规则解析器。

这是一个正则表达式,用于验证规则是否完整且有效:

/^\w+ \| (?: (?:\w+ | \w+=\{(?:[\w.]+,?)+\} | \w+=[\w.]+) (?:,|$) )+$/ix

我想要匹配的是这种格式的字符串:

identifier | options

其中options是以逗号分隔的列表:

  • flag\w的序列)
  • key=value
  • list={1,2,45,foo_bar,with.dot}

它有效,但在逗号后面有一些问题:

  1. 这不应该匹配(末尾有逗号):

    potato|lemon,aa=bb,list={12,45,a.b,_s},foo,yes=no,
    
  2. 列表末尾的逗号:

    potato|lemon,aa=bb,list={12,45,a.b,_s,},foo,yes=no
    
  3. 欢迎提出建议 - 随时tinker

4 个答案:

答案 0 :(得分:4)

更新解决方案:由于您不需要特定的群组匹配,我只需继续并在逗号后检查是否有其他角色。这意味着每个匹配的替代方案必须以\w开头(我在演示中匹配只是为了视觉理解)

 (?:,\w)list={X,Y,Z},字符串结尾为(,\w)?

检查出来:http://regex101.com/r/hF3pO2/7

^ \w+ \| (?: (?: \w+ | \w+=\{ (?:[\w.]+ (?:,\w)?)+ \} | \w+=[\w.]+ ) (,\w)? )+$

使用gixm标志


旧的(接近但不完全)解决方案:

我不是正则表达式的超级专业人士,所以也许有更好的方法,但我可以用这个验证字符串的结尾不是,$

(?:,[^$]|[^,]$)

所以我添加了list={X,Y,Z}和行尾。整个正则表达式现在看起来像这样:

^ \w+ \| (?: (?: \w+ | \w+=\{ (?:[\w.]+ (?:,[^$]|[^,]$)?)+ \} | \w+=[\w.]+ )(?:,[^$]|[^,]$) )+$

...看看http://regex101.com/r/hF3pO2/3

答案 1 :(得分:3)

如果您只需要检查语法,可以使用:

\A\w+\|(\w++(?:=(?:{[\w.]++(?>,[\w.]+)*}|[\w.]+))?)(?:,(?1))*\z

see the demo (in multiline mode)

答案 2 :(得分:1)

我也会在这里添加我自己的解决方案,只是为了完整性:

^ \w+ \| (?: (?: \w++ | \w++=\{(?:[\w.]++ (?:,(?!\}))?)+\} | \w++=[\w.]++ ) (?:,(?!$))? )+ $

我不确定它是否正确,但我尝试了它并且它有效,所以很有希望。 (try it

答案 3 :(得分:0)

以类似语法的方式编写这种正则表达式的更好方法是:

/
(?(DEFINE)
  (?<entry> (?&identifier) \| (?&options) )
  (?<identifier> \w+ )
  (?<options> (?&option) , (?&options) | (?&option) )
  (?<option> (?&list) | (?&keyvalue) | (?&flag) )  
  (?<flag> \w+ )
  (?<keyvalue> (?&key) = (?&value) )
  (?<key> \w+ )
  (?<value> \w+ )
  (?<list> list= \{ (?&list_entries) \} )
  (?<list_entries> (?&list_entry) , (?&list_entries) | (?&list_entry) )
  (?<list_entry> [A-Za-z0-9._]+ )
)  
^(?&entry)$
/x

查看实际操作:https://laravel.com/docs/5.1/eloquent#querying-soft-deleted-models

它更容易理解和调整,但有一些怪癖。一个是左递归不起作用(您不能使用options: options "," option | option规则,您必须将其指定为options: option "," options | option)。另一个是您只能使用它进行验证,您无法使用这种模式提取数据,因为(?(DEFINE))块中的规则无法捕获。

基于Nikita Popov关于PCRE正则表达式有多强大(而非常规)的文章:https://regex101.com/r/hF3pO2/10