2016-11-02 2 views
3

Я использую Rails 4.2.7 (Ruby 2.3). Я использую следующие разделить строку, основываясь на регулярном выраженииКак я могу определить индексы, где была разделена строка?

my_string.split(/\W+/) 

Мой вопрос, как я могу получить эквивалентный массив чисел, в которой каждое число представляет индекс, где произошли расколы? Если разрывов не произошло, я бы ожидал, что массив будет содержать только элемент с «-1».

+0

Что вы хотите, чтобы произошло, если расщепление регулярное выражение соответствует подстроку, которая имеет более чем 1 символ. \ W + может соответствовать "-" например? –

ответ

1

Итак, вы не хотите делиться, вам просто нужны индексы?

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

Пустой массив означает, что раскол не произошел.

Edit: Сокращенный вариант может быть

"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 

С помощью этой информации можно непосредственно получить массив диапазонов, каждый диапазон составляет смещения подстроки, на котором полоса разделяется.

Вот два примера.

# 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] 
Смежные вопросы