【问题标题】:Match comma separated list with Ruby Regex用 Ruby Regex 匹配逗号分隔的列表
【发布时间】:2012-05-09 04:51:52
【问题描述】:

鉴于以下字符串,我想匹配列表中的元素和冒号后的其余部分:

foo,bar,baz:某事

即我期望前三个匹配组是“foo”、“bar”、“baz”。没有逗号,也没有冒号。元素的最小数量是 1,并且可以有任意多个。假设没有空格和小写。

我试过这个,应该可以,但由于某种原因没有填充所有匹配组:

^([a-z]+)(?:,([a-z]+))*:(something)

匹配 \1 中的 foo 和 \2 中的 baz (或任何最后一个元素)。我不明白为什么我没有得到 bar 的匹配组。

有什么想法吗?

编辑:Ruby 1.9.3,如果这很重要的话。

EDIT2:Rubular 链接:http://rubular.com/r/pDhByoarbA

EDIT3:在末尾添加冒号,因为我不只是想匹配列表。抱歉,问题过于简单了。

【问题讨论】:

    标签: ruby regex oniguruma


    【解决方案1】:

    也许split 会是这种情况下更好的解决方案?

    'foo,bar,baz'.split(',')
    => ["foo", "bar", "baz"]
    

    【讨论】:

    • 我知道我可以拆分。这在正则表达式中应该是可能的,只是一个改进我的正则表达式的练习。不过谢谢!
    • 实际上,如果逗号可能出现在带引号的字符串中,str.split() 会做错事。 OP 没有具体说明他的实际输入是什么 - 但需要考虑一些事情。 ;)
    【解决方案2】:

    这个表达式对我有用:/(\w+)/i

    【讨论】:

    • 好电话。如果列表后面还有其他必须匹配的东西,它就不起作用了,最简单的是 $。让我更新我的问题。谢谢!
    • 所以您要为第三组匹配“baz:”?
    • 不,只是巴兹。没有冒号。该列表是较大字符串的一部分。我认为省略其中一些会有所帮助,但确实造成了混乱。对此感到抱歉。
    • 正确。抱歉,在 : 之后还有更多我想匹配的内容,所以一旦将冒号添加到正则表达式中,它就不会匹配列表中的所有内容。
    • 查看最新的 rubular 链接。再次为您的困惑感到抱歉。
    【解决方案3】:

    如果你想用正则表达式来做,这个怎么样?

    (?<=^|,)("[^"]*"|[^,]*)(?=,|$)
    

    这匹配逗号分隔的字段,包括逗号出现在 123,"Yes, No" 等带引号的字符串中的可能性。 Regexr for this.

    更详细:

    (?<=^|,)       # Must be preceded by start-of-line or comma
    (
        "[^"]*"|   # A quote, followed by a bunch of non-quotes, followed by quote, OR
        [^,]*      # OR anything until the next comma
    )
    (?=,|$)        # Must end with comma or end-of-line
    

    使用类似于 Python 的 re.findall() 的东西,它返回字符串中所有不重叠的匹配项(如果重要的话,从左到右工作。)不要将它与您的 re.search() 或 @ 等价物一起使用987654331@ 仅返回找到的第一个匹配项。

    (注意:这实际上在 Python 中不起作用,因为后面的 (?&lt;=^|,) 不是固定宽度。Grr。欢迎对此提出建议。)


    编辑:使用非捕获组来使用行首或逗号,而不是后视,它适用于 Python。

    >>> test_str = '123,456,"String","String, with, commas","Zero-width fields next",,"",nyet,123'
    >>> m = re.findall('(?:^|,)("[^"]*"|[^,]*)(?=,|$)',test_str)
    >>> m
    ['123', '456', '"String"', '"String, with, commas"',
     '"Zero-width fields next"', '', '""', 'nyet', '123']
    

    编辑 2:Python 的 re.findall(needle, haystack)Ruby equivalenthaystack.scan(needle)

    【讨论】:

    • 谢谢,但这不是 Ruby,它对我的​​需要来说太过分了。它也没有解决问题,这与我发布它时略有不同。很抱歉造成混乱!
    • @Christoph: You can't pull out an arbitrary number of match groups (\1, \2, \3...) with one match. 你需要string.scan(pattern)。此外,该示例在 Python 中的事实在 Ruby 中使用它也没有障碍 - 正则表达式是 mostly the same between them.
    • 是的,也许。或者像这里解释的那样捕获一个重复组:regular-expressions.info/captureall.html
    • @Christoph:这基本上是建议您将整个正则表达式包装在一个捕获括号组中。那仍然只会给你一组,\1:foo,bar,baz(这对你来说可能已经足够好了。)如果有任意数量的字段,你不能得到foobarbaz分别为\1, \2, \3。如果你需要,你需要 Ruby 的string.scan()
    【解决方案4】:

    如果我正确解释了您的帖子,您希望在冒号 (:) 之前用逗号分隔所有内容

    适合的正则表达式是:

    [^\s:]*(,[^\s:]*)*(:.*)?
    

    这应该会找到您要查找的所有内容。

    【讨论】:

      猜你喜欢
      • 2015-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多