【问题标题】:Regular expression help - comma delimited string正则表达式帮助 - 逗号分隔的字符串
【发布时间】:2011-09-20 20:55:30
【问题描述】:

我不会写很多正则表达式,所以我需要一些帮助。

我需要一个正则表达式来验证字符串是否为字母数字逗号分隔的字符串。

例子:

  • 123, 4A67, GGG, 767 将是有效的。
  • 12333, 78787&*, GH778 无效
  • fghkjhfdg8797< 无效

这是我目前所拥有的,但不太正确:^(?=.*[a-zA-Z0-9][,]).*$

有什么建议吗?

【问题讨论】:

  • 您的正则表达式的意思是“如果下一位匹配但不消耗任何一个字符,然后是 az、AZ 或 0-9 中的一个,后跟以下之一:逗号。然后在字符串结尾之前消耗任何一个字符。”这不可能匹配任何东西,因为非消费部分必须匹配三个字符,包括尾随逗号,然后才能匹配一个东西。
  • @markets:OP 没有使用代码格式,因此两个 * 量词不可见。正则表达式仍然是错误的,但现在它更有意义了。 ;) @JohnH:如果你使用 SO 的格式化工具,你会得到更好的结果;他们非常好。

标签: regex vb.net


【解决方案1】:

听起来你需要这样的表达式:

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

Posix 允许更自我描述的版本:

^[[:alnum:]]+(,[[:alnum:]]+)*$
^[[:alnum:]]+([[:space:]]*,[[:space:]]*[[:alnum:]]+)*$  // allow whitespace

如果您也愿意接受下划线,请搜索整个单词 (\w+):

^\w+(,\w+)*$
^\w+(\s*,\s*\w+)*$  // allow whitespaces around the comma

【讨论】:

  • 这个答案的几个问题:(1)不能直接使用POSIX“字符类”;它必须用另一组方括号括起来,例如[[:alnum:]]+。但这是学术性的,因为 .NET 不支持它们(即使是不同的形式,如 Java 的 \p{Alnum})。 (2) \w 和所有字符类简写(\s\d 等)一样,只匹配一个字母,所以你应该使用\w+。 (3) 您不允许标记之间有空格。
  • @Alan:谢谢,已修复!顺便问一下,Emacs 中的“空白”是什么? \s 似乎不起作用...
  • 我不使用 Emacs,但根据this,它是\s-\s 本身不匹配任何东西;它只是将以下字符标记为特殊字符。
【解决方案2】:

请使用 - ^((([a-zA-Z0-9\s]){1,45},)+([a-zA-Z0-9\s]){1,45})$

这里我设置了最大字数为45,因为英文的最长单词是45个字符,可以根据需要更改

【讨论】:

    【解决方案3】:

    试试^(?!,)((, *)?([a-zA-Z0-9])\b)*$

    分步说明:

    • 不要匹配开头的逗号(有利于即将到来的“循环”)。
    • 匹配可选的逗号和空格。
    • 匹配你喜欢的字符。
    • 单词边界的匹配确保如果更多参数堆叠在字符串中,逗号是必要的。

    【讨论】:

      【解决方案4】:

      试试下面的表达式:

      /^([a-z0-9\s]+,)*([a-z0-9\s]+){1}$/i

      这适用于:

      1. 测试
      2. 测试,测试
      3. 测试123,测试123,测试

      我强烈建议修剪逗号分隔列表中每个项目开头和结尾的空格。

      【讨论】:

        【解决方案5】:

        是的,当你想捕捉逗号分隔的东西时,最后一个逗号是合法的,并且匹配到$LONGSTUFF,你必须重复$LONGSTUFF

        $LONGSTUFF(,$LONGSTUFF)*
        

        如果$LONGSTUFF 真的很长并且本身包含逗号重复的项目等,那么手动构建正则表达式可能是个好主意,而是依靠计算机为您完成,即使它只是通过字符串连接。例如,我只想构建一个正则表达式来验证 XEN configuration file 的 CPUID 参数,['1:a=b,c=d','2:e=f,g=h'] 类型。我...相信这很符合要求:(尽管有空格!)

        xend_fudge_item_re = r"""
          e[a-d]x=          #register of the call return value to fudge
          (
            0x[0-9A-F]+ |   #either hardcode the reply
            [10xks]{32}     #or edit the bitfield directly
          )
        """
        xend_string_item_re = r"""
          (0x)?[0-9A-F]+:   #leafnum (the contents of EAX before the call)
          %s                #one fudge
          (,%s)*            #repeated multiple times
        """ % (xend_fudge_item_re, xend_fudge_item_re)
        xend_syntax = re.compile(r"""
          \[                #a list of
           '%s'             #string elements
           (,'%s')*         #repeated multiple times
          \]
          $                 #and nothing else
        """ % (xend_string_item_re, xend_string_item_re), re.VERBOSE | re.MULTILINE)
        

        【讨论】:

        • 请注意,上述 RE 存在一些问题,包括但不限于缺少空格支持和区分大小写,这使其不适合生产。固定版本要长得多,然后您就会开始错过答案的重点。这只是一个例子,说明如何理智地处理更复杂的情况。
        • 我最终没有使用那个正则表达式 - 所以here's the full shebang
        【解决方案6】:

        你似乎缺乏重复。怎么样:

        ^(?:[a-zA-Z0-9 ]+,)*[a-zA-Z0-9 ]+$
        

        我不确定你会如何在 VB.Net 中表达这一点,但在 Python 中:

        >>> import re
        >>> x [ "123, $a67, GGG, 767", "12333, 78787&*, GH778" ]
        >>> r = '^(?:[a-zA-Z0-9 ]+,)*[a-zA-Z0-9 ]+$'
        >>> for s in x:
        ...    print re.match( r, s )
        ...
        <_sre.SRE_Match object at 0xb75c8218>
        None
        >>>>
        

        您可以使用快捷方式而不是列出 [a-zA-Z0-9 ] 部分,但这可能更容易理解。

        分析亮点:

        • [a-zA-Z0-9 ]+ :捕获列出的范围中的一个或多个(但不为零)和空格。
        • (?:[...]+,)* :在非捕获括号中,匹配一个或多个字符,最后加上逗号。匹配这样的序列零次或多次。捕获零次不允许使用逗号。
        • [...]+ :至少捕获其中之一。这不包括逗号。这是为了确保它不接受尾随逗号。如果可以接受尾随逗号,则表达式更简单:^[a-zA-Z0-9 ,]+

        【讨论】:

        • 这允许任何地方的空格,所以它也匹配' abc 123, fo o bar '。也许这对 OP 来说是可以接受的,但我会将空格从字符类中拉出来。
        • @Alan 好点。 OP 根本没有处理空格,但在示例中允许使用它们。正则表达式可以删除现有空格并在逗号前后添加可选空格(空格星号)。
        【解决方案7】:

        试试这个模式:^([a-zA-Z0-9]+,?\s*)+$

        我用你的情况测试了它,以及一个数字“123”。我不知道你会不会一直有逗号。

        [a-zA-Z0-9]+ 表示匹配这些符号中的一个或多个 ,? 表示匹配 0 或 1 个逗号(基本上,逗号是可选的) \s* 处理逗号后的 1 个或多个空格 最后外部+ 表示匹配1 个或多个模式。

        这也将匹配 123 123 abc(没有逗号)这可能是个问题 这也将匹配123,(以逗号结尾),这可能是个问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-09-13
          • 2016-12-03
          相关资源
          最近更新 更多