【问题标题】:ruby regex: match and get position(s) ofruby 正则表达式:匹配并获取位置
【发布时间】:2011-07-11 15:07:18
【问题描述】:

我想匹配一个正则表达式并获取匹配字符串中的位置

例如,

"AustinTexasDallasTexas".match_with_posn /(Texas)/

我希望 match_with_posn 返回如下内容:[6, 17] 其中 6 和 17 是单词 Texas 的两个实例的起始位置。

有这样的吗?

【问题讨论】:

标签: ruby regex


【解决方案1】:

有点,见String#index

"AustinTexasDallasTexas".index /Texas/
=> 6

现在,您可以扩展 String API。

class String
  def indices e
    start, result = -1, []
    result << start while start = (self.index e, start + 1)
    result
  end
end
p "AustinTexasDallasTexas".indices /Texas/
=> [6, 17]

【讨论】:

  • 假设字符串是“aaaa”e”aa”。这个问题不清楚期望的返回值是[0,1,2] 还是[0,2]。你退回前者。要返回后者,使index 的第二个参数start+e.size 并将start 初始化为-e.size。不需要self.
【解决方案2】:

使用 Ruby 1.8.6+,您可以这样做:

require 'enumerator' #Only for 1.8.6, newer versions should not need this.

s = "AustinTexasDallasTexas"
positions = s.enum_for(:scan, /Texas/).map { Regexp.last_match.begin(0) }

这将创建一个数组:

=> [6, 17]

【讨论】:

  • 如果你想在 Isateateestt 中找到atea,它会返回[2],但5也是可能的
  • 索引 5 中的“a”用于匹配索引 2 中的“atea”。如果搜索“ate”,则会得到一个 [2, 5, 8] 数组。如果要查找重叠匹配,请使用前瞻断言:/(?=(atea))/positions = s.enum_for(:scan, /(?=(atea))/).map { Regexp.last_match.begin(0) } #=&gt; [2, 5]
  • 投反对票的人能否解释一下投反对票?
  • 你能详细解释一下吗?
  • 它返回一个scan 的枚举器,它在传递给它的参数的字符串中找到匹配项,在本例中为/Texas/。如果没有枚举器,它通常会返回匹配的字符串部分。由于我们使用的是枚举器,因此我们可以映射匹配项,以便我们可以返回每个 scan 结果的索引。本质上发生的情况是,map 调用中的每个步骤都会在enum_for 返回的枚举器上调用next,然后返回块内的值。
【解决方案3】:
"AustinTexasDallasTexas".gsub(/Texas/).map { Regexp.last_match.begin(0) }
  #=> [6, 17]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-03
    • 2013-06-12
    • 1970-01-01
    • 2021-08-15
    • 2014-11-11
    • 2021-09-05
    • 1970-01-01
    相关资源
    最近更新 更多