我该如何确定字符串被分割的位置索引?

3

我正在使用Rails 4.2.7(Ruby 2.3)。 我使用以下代码基于正则表达式来拆分字符串:

my_string.split(/\W+/)

我的问题是,如何获取一个等价的数组,其中每个数字表示拆分发生的位置的索引?如果没有发生拆分,我希望数组只包含一个元素“-1”。


如果分割正则表达式匹配到一个有超过一个字符的子字符串,你想发生什么?例如,\W+ 可以匹配 " - "。 - Eric Duminil
2个回答

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]

0
在某些情况下,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] 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接