【问题标题】:How do I find the index in a string of where my nth occurrence of a regex ends?如何在第 n 次出现正则表达式的字符串中找到索引?
【发布时间】:2017-07-10 20:35:05
【问题描述】:

在 Ruby 2.4 中使用 Rails 5.0.1。如何在第 n 次出现正则表达式的字符串中找到索引?如果我的正则表达式是

/\-/

我的字符串在哪里

str = "a -b -c"

我正在寻找我的正则表达式第二次出现的最后一个索引,我希望答案是 5。我试过这个

str.scan(StringHelper::MULTI_WHITE_SPACE_REGEX)[n].offset(1)

但是遇到了错误

NoMethodError: undefined method `offset' for "             ":String

在上面,n 是一个整数,表示我希望扫描的正则表达式的第 n 次出现。

【问题讨论】:

  • 我假设您要查找的offset 来自MatchData,在这种情况下请查看"How do I get the match data for all occurrences of a Ruby regular expression in a string?"。一旦你有所有出现的MatchData,你就可以索引到数组中并为特定的出现获取它。 (虽然在给定的正则表达式中你想要offset(0),因为正则表达式中没有任何额外的捕获组)
  • 谢谢。我假设您正在谈论操纵链接中的答案 - “my_string.to_enum(:scan, my_regex).map { Regexp.last_match }”,但我不清楚如何更改它以适应第 n 个匹配我发现的。
  • map 返回一个数组,所以它只是 my_string.to_enum(:scan, my_regex).map { Regexp.last_match }[n - 1].offset(0) 如果我正确理解所有内容(n - 1 表示第 n 个偏移量,因为基于 0 的索引),它应该可以满足您的需求。所以str.to_enum(:scan, /\-/).map { Regexp.last_match }[1].offset(0) => [5, 6]
  • @SimpleLime, "my_string.to_enum(:scan, my_regex).map { Regexp.last_match }[n - 1].offset(0)" 似乎正在工作。如果你想把它作为答案,我会接受。
  • 当然,最初并没有将其作为答案,因为我不确定这是否足够接近以成为该问题的“重复”,但是已经完善了其他答案对于您的情况,可能需要的答案不是 cmets

标签: ruby-on-rails ruby regex lastindexof


【解决方案1】:

来自我的 cmets,它从一个链接变成了 related question

这个问题的答案

"abc12def34ghijklmno567pqrs".to_enum(:scan, /\d+/).map { Regexp.last_match }

可以很容易地适应获取单个项目的 MatchData

string.to_enum(:scan, regex).map { Regexp.last_match }[n - 1].offset(0)

在字符串中查找nth 匹配项。

【讨论】:

    【解决方案2】:

    一种方法:

    def index_of_char str, char, n
      res = str.chars.zip(0..str.size).select { |a,b| a == char }
      res[n]&.last
    end
    
    index_of_char "a -b -c", '-', 0
    #=> 2
    
    index_of_char "a -b -c", '-', 1
    #=> 5
    
    index_of_char "a -b -c", '-', 2
    #=> nil
    
    index_of_char "abc", '-', 1
    #=> nil
    

    可以进行进一步优化。

    【讨论】:

      【解决方案3】:

      很抱歉之前的快速阅读。也许这种方法可以帮助您定位元素的第 n 个出现的索引。虽然我找不到在 ruby​​ 中使用严格的正则表达式来做到这一点的方法。希望这会有所帮助。

      def index_of_nth_occorunce(string, element, nth_occurunce)
        count = 0
        string.split("").each_with_index do |elm, index| 
          count += 1 if elm == element
          return index if count == nth_occurunce
        end
      end
      
      index_of_nth_occorunce("a -b -c", "-", 2) #5
      

      在进一步挖掘之后,我可能在此堆栈帖子 (ruby regex: match and get position(s) of) 中找到了您正在寻找的答案。希望这也有帮助。

      nth_occurence = 2 
      s = "a -b -c"
      positions = s.enum_for(:scan, /-/).map { Regexp.last_match.begin(0) }
      p positions[nth_occurence - 1] # 5
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多