【问题标题】:How do I figure out the indexes of where a string was split?如何找出字符串被分割的位置的索引?
【发布时间】:2016-11-02 21:20:57
【问题描述】:

我使用的是 Rails 4.2.7 (Ruby 2.3)。我使用以下内容根据正则表达式拆分字符串

my_string.split(/\W+/)

我的问题是,我怎样才能得到一个等价的数字数组,其中每个数字代表分裂发生位置的索引?如果没有发生拆分,我希望数组只包含一个带有“-1”的元素。

【问题讨论】:

  • 如果拆分正则表达式匹配具有超过 1 个字符的子字符串,您希望发生什么。 \W+ 例如可以匹配“ - ”?

标签: ruby string split


【解决方案1】:

所以,你不想拆分,你只想要索引?

a = []
"Hello stack overflow".scan(/\W+/){a<<Regexp.last_match.begin(0)}
a
#=> [5, 11]

空数组意味着没有发生拆分。

编辑:更短的版本可能是

"Hello stack overflow".enum_for(:scan, /\W+/).map{Regexp.last_match.begin(0)}
#=> [5, 11]

【讨论】:

    【解决方案2】:

    在某些情况下,String#split 会将字符串拆分为具有多个字符的子字符串。每个子字符串开头的字符串偏移量可能不够。可能需要开始和结束索引。

    以下方法返回一个元组数组,每个元组的第一个元素是strip 返回的字符串部分,第二个元素是该子字符串开始的索引。请注意,这不仅提供了一种计算所需索引的方法,而且还返回了 split 返回的子字符串。

    def split_with_offsets(str, r)
      indices = []
      str.scan(r) { indices << Regexp.last_match.begin(0) }
      str.split(r).zip(indices << str.size).map { |s,ndx| [s, ndx-s.size] }
    end
    

    有了这些信息,就可以直接获得一个范围数组,每个范围都是分割条的子字符串的偏移量。

    def gaps(str, r)
      split_with_offsets(str, r).each_cons(2).map { |(s,f), (_,lp1)| f+s.size..lp1-1 }
    end
    

    这里有两个例子。

    #1

    str = "Hello stack overflow"
    r = /\W+/
    
    split_with_offsets(str, r)
      #=> [["Hello", 0], ["stack", 6], ["overflow", 12]] 
    gaps(str, r)
      #=> [5..5, 11..11]
    

    #2

    str = "I | cannot | wait | for |    the election |to |be  | over"
    r = /\s*\|\s*/ 
    
    split_with_offsets(str, r)
      #=> [["I", 0], ["cannot", 4], ["wait", 13], ["for", 20], ["the election", 29],
      #    ["to", 43], ["be", 47], ["over", 53]] 
    gaps(str, r)
      #=> [1..3, 10..12, 17..19, 23..28, 41..42, 45..46, 49..52] 
    

    【讨论】:

      猜你喜欢
      • 2011-03-26
      • 2021-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多