逗号分隔列表的正则表达式模式是什么?

时间:2017-10-02 23:00:34

标签: php regex

有时我需要确保某些输入是以逗号分隔(或任何分隔)的结构良好的数据列表。例如,在现实世界中,我需要验证这种格式:foo{bar:baz,abc:def},xyz,lol{rotfl:true},它是逗号分隔的字符串列表,包含或不包含参数列表(也以逗号分隔)。这个例子比较复杂,我只是提一下,以防止你们给出平庸的答案,如:

  

为什么你不能使用explode()?

每当我想要更好地了解正则表达式时,我总能得到它。

为简单起见,我将使用另一个例子。但请记住:这不是实际问题!它是更复杂的用例的简化示例,我确实必须使用正则表达式。

让我们说我需要一个正则表达式模式来确保我的字符串是逗号分隔的邮政编码列表。每个邮政编码的格式为xx-xxx,其中x是0到9之间的任意数字,并且至少有一个邮政编码。该列表需要以逗号分隔,这意味着:

  1. 没有引导逗号
  2. 没有尾随逗号
  3. 不超过一个连续的逗号
  4. 通常情况下,我会这样做:

    $pattern = '#^\d{2}-\d{3}(?:,\d{2}-\d{3})*$#';
    

    那会有效。有没有办法阻止重复模式的\d{2}-\d{3}部分?当然,我可以将它保存到变量中:

    $zipCodePattern = '\d{2}-\d{3}';
    $pattern        = "#^$zipCodePattern(?:,$zipCodePattern)*$#";
    

    虽然如果可以在模式本身中完成,我感到好奇。

3 个答案:

答案 0 :(得分:2)

使用以下正则表达式模式:

^(\d{2}-\d{3}\b(,(?!$))?)+$

https://regex101.com/r/E1yHVY/7

答案 1 :(得分:1)

这使用+来匹配一次和无限次的邮政编码。在非捕获组内部,(?:,|$)仅允许匹配组,如果它是字符串的末尾,则不使用分隔符,如果列表中只有一个代码,则可以使用它。最后,使用负面的后视来确保没有尾随分隔符。

^(?:\d{2}-\d{3}(?:,|$))+(?<!,)$

答案 2 :(得分:-1)

我认为解决此问题的最佳方法是使用implode()explode()函数。您是否有理由使用正则表达式进行此操作?