Как обратная ссылка в регулярном выражении Ruby (regex) с gsub при использовании группировки?
Я хотел бы исправить некоторые текстовые данные, извлеченные из веб-страниц.
Образец:
t="First sentence. Second sentence.Third sentence."
В конце второго предложения нет пробела после точки. Это означает, что 3-е предложение было в отдельной строке (после тега br) в исходном документе.
Я хочу использовать это регулярное выражение для вставки символа "\n" в нужные места и исправления моего текста.
Мое регулярное выражение:
t2=t.gsub(/([.\!?])([A-Z1-9])/,$1+"\n"+$2)
Но, к сожалению, это не работает: "NoMethodError: undefined метод` + 'для nil: NilClass"
Как я могу правильно отнестись к сопоставленным группам?
Это было так просто в Microsoft Word, мне просто пришлось использовать символы \1 и\2.
Ответы
Ответ 1
Вы можете выполнить обратную ссылку в строке подстановки с помощью \1
(для соответствия группе захвата 1).
t = "First sentence. Second sentence.Third sentence!Fourth sentence?Fifth sentence."
t.gsub(/([.!?])([A-Z1-9])/, "\\1\n\\2") # => "First sentence. Second sentence.\nThird sentence!\nFourth sentence?\nFifth sentence."
Ответ 2
- Если вы используете
gsub(regex, replacement)
, используйте '\1'
, '\2'
,... для ссылки на совпадение. Не ставьте двойные кавычки вокруг replacement
, иначе избегайте обратную косую черту, как в ответе Джошуа. Преобразование из '\1'
в соответствие будет выполнено в пределах gsub
, а не буквальной интерпретацией.
- Если вы используете
gsub(regex){replacement}
, используйте $1
, $1
,...
Но для вашего случая легче использовать совпадения:
t2 = t.gsub(/(?<=[.\!?])(?=[A-Z1-9])/, "\n")
Ответ 3
Если вы попали сюда из-за жалобы Rubocop "Избегайте использования backref-стиля в стиле Perl". около $1, $2 и т.д., вы можете сделать это вместо этого:
some_id = $1
# or
some_id = Regexp.last_match[1] if Regexp.last_match
some_id = $5
# or
some_id = Regexp.last_match[5] if Regexp.last_match
Он также захочет, чтобы вы сделали
%r{//}.match(some_string)
вместо
some_string[//]
Lame (Rubocop)