Ruby正则表达式帮助

3

我正在尝试在Ruby中使用正则表达式解析模式。该模式类似于:

<number>? <comma>? <number>? <term>*

where:

  • number代表一个或多个数字
  • comma代表英文逗号","
  • term的格式为[.*][^.*]

我正在尝试捕获数字和所有术语。为了澄清,这里有一些有效模式的示例:

5,50[foo,bar]
5,[foo][^apples]
10,100[baseball][^basketball][^golf]
,55[coke][pepsi][^drpepper][somethingElse]

首先,我想捕获550[foo,bar]

其次,我想捕获5[foo][^apples]等。

我设计的模式如下:

/(\d+)?,?(\d+)?(\[\^?[^\]]+\])+/

但是这只匹配数字和最后一个术语。如果我在末尾删除+,那么它只匹配第一个术语。
2个回答

1
我能想到最简单的解决方法,而且付出最少的努力就是在已经有的组和+周围添加一个额外的捕获组。即:
/(\d+)?,?(\d+)?((\[\^?[^\]]+\])+)/

此外,你可以通过使用(\d*)代替(\d+)?来简化\d表达式...

编辑

以下是用于测试上述建议的代码:

matches = [ "5,50[foo,bar]",
            "5,[foo][^apples]",
            "10,100[baseball][^basketball][^golf]",
            ",55[coke][pepsi][^drpepper][somethingElse]"
          ]

re = Regexp.new('(\d*),?(\d*)((\[\^?[^\]]+\])+)')

matches.each do |match|
  m = re.match(match)

  puts "\nMatching: #{match}"
  puts "--------------------"

  puts "Match 1: #{m[1]}"
  puts "Match 2: #{m[2]}"
  puts "Match 3: #{m[3]}"
end

以及输出:

Matching: 5,50[foo,bar]
--------------------
Match 1: 5
Match 2: 50
Match 3: [foo,bar]

Matching: 5,[foo][^apples]
--------------------
Match 1: 5
Match 2: 
Match 3: [foo][^apples]

Matching: 10,100[baseball][^basketball][^golf]
--------------------
Match 1: 10
Match 2: 100
Match 3: [baseball][^basketball][^golf]

Matching: ,55[coke][pepsi][^drpepper][somethingElse]
--------------------
Match 1: 
Match 2: 55
Match 3: [coke][pepsi][^drpepper][somethingElse]

编辑 2

如果您想要进行标记化,可以按照 J-_-L 的建议使用 scan 方法,添加:

m[3].scan(/\[\^?[^\]]+\]/)

我已经在Ruby和JavaScript中尝试过这个问题,但是返回的结果是所有术语组合在一起,只有最后一个术语单独返回。由于它返回了所有术语的组合 - 在第二个例子中[foo][^apples],并且最后一个术语单独返回 - [^apples],我猜测它能够找到匹配项,但是输出结果中没有出现。不知道我错过了什么。 - Anurag
可能我误解了什么......你是想有效地标记每个“项”吗?如果是这样,那么正则表达式不是用于标记化部分的方法,只需在捕获所有“项”后基于][进行拆分--据我所知,没有一种语言允许在其正则表达式引擎中具有可变数量的捕获组。我在Ruby中编写了一个快速且不完美的检查,我将其作为编辑发布。告诉我是否误读了你的问题。 - photoionized
感谢您提出拆分原始输入并扫描分组字符串的建议,它很好地解决了问题。 - Anurag

1

这是与此处相同的问题 - 您只有固定数量的捕获组。

在您的情况下,我建议拆分字符串(例如使用photoionized的方法),然后使用scan(例如使用(\[\^?[^\]]+\]))来获取组。


@J - 谢谢。它很好用。我打算使用treetop并创建一个小的解析器来完成这个任务,因为这样感觉更加清晰。感谢你的帮助。 - Anurag

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接