ruby - 使用 Ruby 扫描方法,捕获组无法按预期工作

标签 ruby regex

我需要从多行字符串中获取一组 float (包括正数和负数)。例如:-45.124、1124.325

这是我的做法:

text.scan(/(\+|\-)?\d+(\.\d+)?/)

虽然它在 regex101 上运行良好(捕获组 0 匹配我需要的一切),它在 Ruby 代码中不起作用。

知道为什么会这样吗?我该如何改进?

最佳答案

参见 scan documentation:

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(如果您只需要对一系列模式进行分组以便能够对其进行量化),或者使用额外的代码/组如果无法避免捕获组。

  1. 在这种情况下,捕获组用于量化模式序列,因此您需要做的就是通过替换所有未转义的( (?: (这里只出现一次):
text = " -45.124, 1124.325"
puts text.scan(/[+-]?\d+(?:\.\d+)?/)

参见 demo ,输出:

-45.124
1124.325

好吧,如果您还需要匹配像 .04 这样的 float ,您可以使用 [+-]?\d*\.?\d+。见 another demo

  1. 有些情况下您无法摆脱捕获组,例如当正则表达式包含对捕获组的反向引用时。在这种情况下,您可以 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/

相关文章:

java - 使用 Matcher.find() 时出现 IndexOutOfBoundsException

java - 限制用户在服务器上执行的各种正则表达式模式

c# - 当字段中存在逗号和括号时如何解析逗号分隔的字符串

ruby-on-rails - rails 引擎 : render parent application layout

ruby-on-rails - main :Object 的未定义方法复数

Javascript正则表达式匹配单词并计算每个单词出现的次数

c++ - GCC 和 MSVC 之间 std::regex_replace 行为的差异

ruby - 向 Ruby 的最后一个参数魔术哈希添加一个非文字哈希元素?

ruby - Ruby 的双冒号 `::` 是什么?

ruby - 如何在 Ruby 中将 URL 分成两部分?