我需要从多行字符串中获取一组 float (包括正数和负数)。例如:-45.124、1124.325
等
这是我的做法:
text.scan(/(\+|\-)?\d+(\.\d+)?/)
虽然它在 regex101 上运行良好(捕获组 0 匹配我需要的一切),它在 Ruby 代码中不起作用。
知道为什么会这样吗?我该如何改进?
最佳答案
If the pattern contains no groups, each individual result consists of the matched string,
$&
. If the pattern contains groups, each individual result is itself an array containing one entry per group.
您应该删除捕获组(如果它们是多余的),或者将它们设为 non-capturing(如果您只需要对一系列模式进行分组以便能够对其进行量化),或者使用额外的代码/组如果无法避免捕获组。
- 在这种情况下,捕获组用于量化模式序列,因此您需要做的就是通过替换所有未转义的
(
和(?:
(这里只出现一次):
text = " -45.124, 1124.325"
puts text.scan(/[+-]?\d+(?:\.\d+)?/)
参见 demo ,输出:
-45.124
1124.325
好吧,如果您还需要匹配像 .04
这样的 float ,您可以使用 [+-]?\d*\.?\d+
。见 another demo
- 有些情况下您无法摆脱捕获组,例如当正则表达式包含对捕获组的反向引用时。在这种情况下,您可以 a) 声明一个变量来存储所有匹配并将它们全部收集在
scan
block 中,或者 b) 用另一个捕获组包围整个模式并映射结果以获得每个匹配项的第一项,c) 您可以使用仅包含正则表达式的gsub
作为单个参数来返回 Enumerator,使用.to_a
获取匹配项数组:
text = "11234566666678"
# Variant a:
results = []
text.scan(/(\d)\1+/) { results << Regexp.last_match(0) }
p results # => ["11", "666666"]
# Variant b:
p text.scan(/((\d)\2+)/).map(&:first) # => ["11", "666666"]
# Variant c:
p text.gsub(/(\d)\1+/).to_a # => ["11", "666666"]
参见 this Ruby demo。
关于ruby - 使用 Ruby 扫描方法,捕获组无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31319067/