Ответ 1
Вы можете использовать глобальную переменную .scan
и $`
, что означает строку слева от последнего успешного совпадения, но она не работает внутри обычного .scan
, поэтому вам нужен этот хак (украденный с этот ответ):
string = "Jack and Jill went up the hill to fetch a pail of water. Jack fell down and broke his crown. And Jill came tumbling after. "
string.to_enum(:scan, /(jack|jill)/i).map do |m,|
p [$`.size, m]
end
выход:
[0, "Jack"]
[9, "Jill"]
[57, "Jack"]
[97, "Jill"]
UPD:
Обратите внимание на поведение lookbehind - вы получаете индекс действительно подобранной части, а не внешний вид:
irb> "ab".to_enum(:scan, /ab/ ).map{ |m,| [$`.size, $~.begin(0), m] }
=> [[0, 0, "ab"]]
irb> "ab".to_enum(:scan, /(?<=a)b/).map{ |m,| [$`.size, $~.begin(0), m] }
=> [[1, 1, "b"]]