【问题标题】:Regex for Comma delimited list逗号分隔列表的正则表达式
【发布时间】:2010-11-26 15:13:56
【问题描述】:

验证逗号分隔列表的正则表达式是什么:

12365, 45236, 458, 1, 99996332, ......

【问题讨论】:

  • 是否会有转义字符,例如:12365,45236,"This is a \"test."
  • 为什么必须是正则表达式?根据语言的不同,您最好使用内置的 CSV 解析器。

标签: regex csv


【解决方案1】:

以下将匹配任何逗号分隔的单词/数字/空格组合

(((.)*,)*)(.)*

【讨论】:

  • 当您想要逗号分隔值时,该正则表达式没有用。它允许单词;词;词...
【解决方案2】:

我建议你这样做:

(\d+)(,\s*\d+)*

这适用于包含 1 个或多个元素的列表。

【讨论】:

  • 你说得对,我必须先去掉第一个字符才能使用正则表达式,谢谢大家的帮助
  • @ondrobaco:您可能只检查了第一个匹配组。下一个匹配组将包含列表的其余部分。
  • 上述解决方案不会验证空列表。 (^$)|(^(\d+)(,\s*\d+)*$) 可能会起作用。
  • @Val:your solution 的问题在于它不会匹配根本没有逗号的列表,例如"1""12345"。这些列表不包含多个项目,因此它们没有逗号。而您的正则表达式(\d+,)* 要求每个数字后跟一个逗号。
  • 如何匹配/提取每个元素(使用正则表达式)?
【解决方案3】:

在 JavaScript 中,使用 split 来帮忙,并捕获任何负数:

'-1,2,-3'.match(/(-?\d+)(,\s*-?\d+)*/)[0].split(',');
// ["-1", "2", "-3"]
// may need trimming if digits are space-separated

【讨论】:

    【解决方案4】:

    此正则表达式从逗号分隔列表中提取一个元素,而不考虑内容:

    (.+?)(?:,|$)
    

    如果你只是用其他东西替换逗号,它应该适用于任何分隔符。

    【讨论】:

    • 它是否提取了多个元素?
    • 为了处理逗号后的空格,就像在 OP 中一样,我建议稍微修改一下:(.+?)(?:,\s*|$)
    • @paranza - 是的,这将提取多个元素,但前提是启用了全局匹配,您使用的任何函数都会返回所有匹配项,而不仅仅是第一个匹配项。在过去,您通过在结束斜杠后添加一个“g”来做到这一点(例如,/expr/g),但显然它并不是那么标准。例如,在 PHP 中,您必须使用 preg_match_all() 而不是 preg_match()。其他风格的正则表达式有其他方法。
    【解决方案5】:

    如果这对您很重要,此选项将拒绝行首或行尾多余的逗号。

    ((, )?(^)?(possible|value|patterns))*
    

    possible|value|patterns 替换为与您的允许值匹配的正则表达式。

    【讨论】:

      【解决方案6】:

      我有一个稍微不同的要求,用转义逗号解析编码的字典/哈希表,如下所示:

      "1=This is something, 2=This is something,,with an escaped comma, 3=This is something else"
      

      我认为这是一个优雅的解决方案,其技巧可以避免大量正则表达式的复杂性:

      if (string.IsNullOrEmpty(encodedValues))
      {
          return null;
      }
      else
      {
          var retVal = new Dictionary<int, string>();
          var reFields = new Regex(@"([0-9]+)\=(([A-Za-z0-9\s]|(,,))+),");
          foreach (Match match in reFields.Matches(encodedValues + ","))
          {
              var id = match.Groups[1].Value;
              var value = match.Groups[2].Value;
              retVal[int.Parse(id)] = value.Replace(",,", ",");
          }
          return retVal;
      }
      

      我认为它可以用@"([0-9]+),\s?" 之类的表达式适应原始问题并在Groups[0] 上解析。

      我希望它对某人有所帮助,并感谢您提供接近那里的提示,尤其是 Asaph!

      【讨论】:

        【解决方案7】:

        我用它来列出每个项目前面必须是字母数字且没有下划线的项目。

        ^(([0-9a-zA-Z][0-9a-zA-Z_]*)([,][0-9a-zA-Z][0-9a-zA-Z_]*)*)$
        

        【讨论】:

          【解决方案8】:

          匹配重复的逗号分隔项:

          (?<=,|^)([^,]*)(,\1)+(?=,|$)
          

          Reference.

          此正则表达式可用于拆分逗号分隔列表的值。列表元素可以带引号、不带引号或为空。一对引号内的逗号不匹配。

          ,(?!(?<=(?:^|,)\s*"(?:[^"]|""|\\")*,)(?:[^"]|""|\\")*"\s*(?:,|$))
          

          Reference.

          【讨论】:

          • 管道符号 (|) 到底在做什么?这是您链接到的页面中没有解释的一个符号,我无法理解。
          • @ThomasVanderStichele:这是为了交替。 (foo|bar) 匹配 foobar。欲了解更多信息:regular-expressions.info/alternation.html
          【解决方案9】:

          这在一定程度上取决于您的具体要求。我假设:所有数字,任何长度,数字都不能有前导零,也不能包含逗号或小数点。单个数字总是用逗号分隔,然后是空格,最后一个数字后面没有逗号和空格。任何这些错误都会简化解决方案。

          ([1-9][0-9]*,[ ])*[1-9][0-9]*

          这是我在心理上的构建方式:

          [0-9]  any digit.
          [1-9][0-9]*  leading non-zero digit followed by any number of digits
          [1-9][0-9]*, as above, followed by a comma
          [1-9][0-9]*[ ]  as above, followed by a space
          ([1-9][0-9]*[ ])*  as above, repeated 0 or more times
          ([1-9][0-9]*[ ])*[1-9][0-9]*  as above, with a final number that doesn't have a comma.
          

          【讨论】:

          • 我发现这个答案真的很有用,只需要稍微调整一下就可以在逗号之前和之后接受空格 ([1-9][0-9]*[ ]*,[ ]*)*[1-9][0-9]* ...也许有人会觉得这很有用
          • 我最喜欢这个例子,在这之后如何允许换行?
          【解决方案10】:
          /^\d+(?:, ?\d+)*$/
          

          【讨论】:

            【解决方案11】:

            为了安全起见,您可能想指定语言,但是

            (\d+, ?)+(\d+)?
            

            应该可以工作

            【讨论】:

            • 对于仅包含 1 个元素的列表,此解决方案失败。请参阅下面的解决方案。