С помощью String#gsub
я могу вставить строки разрыва в атрибут replace:
"my string".gsub(/\s/, "\n") #=> "my\nstring"
Но если я также хочу использовать часть совпадения регулярного выражения в атрибуте replace, я буду вынужден использовать одинарные квоты ('). И тогда я не знаю, как вставить разрывную линию.
Я пробовал:
> "my string".gsub!(/(my )/, '\1\n')
=> "my \\nstring"
> "my string".gsub!(/(my )/, '\1\\n')
=> "my \\nstring"
> "my string".gsub!(/(my )/, '\1\\\n')
=> "my \\nstring"
> "my string".gsub!(/(my )/, '\1\\\\n')
=> "my \\nstring"
> "my string".gsub!(/(my )/, '\1\\\\\n')
=> "my \\\\nstring"
> "my string".gsub!(/(my )/, '\1\\\\\n')
=> "my \\\\nstring"
Ничего не работает.
Вам не нужно использовать одинарные кавычки. Просто используйте двойные кавычки и замените \1
на \\1
:
irb> "my string".gsub(/(my )/, "\\1\n")
=> "my \nstring"
Разница между одинарными и двойными кавычками заключается в том, что в строках с одинарными кавычками нельзя использовать escape-последовательности (кроме одинарных кавычек). Эти строки эквивалентны:
irb> '\1' == "\\1"
=> true
irb> '\n' == "\\n"
=> true
Это упоминается в документации: «Обратной ссылке обычно предшествует дополнительная обратная косая черта. Например, если вы хотите записать обратную ссылку \&
в replacement
со строковым литералом в двойных кавычках, вам нужно написать "..\\&.."
». . Раньше он был прямо в документации для String#gsub , но с тех пор был перенесен в общую документацию для Методы замены
@engineersmnky, но это не сработало "my string".gsub!(/(my )/, '\1\\n') #=> "my \\nstring"
@fguillen в документации указано, хотите ли вы написать обратную ссылку... со строковым литералом в двойных кавычках. Вы сравниваете это утверждение с разрывом строки в литерале, заключенном в одинарные кавычки.
Вы можете использовать несколько стилей кавычек одновременно. Хотя это используется редко, в Ruby вы можете смешивать и сопоставлять строковые литералы с разными стилями кавычек.
Из документации:
Любая комбинация соседних строк с одинарными, двойными кавычками и процентами будет объединяться, если строка с процентами не является последней.
Применительно к вашей проблеме:
"my string".gsub(/(my )/, '\1' "\n")
#=> "my \nstring"
В приведенном выше коде '\1' "\n"
представляет один экземпляр строки. Вы также можете вставить эти объединенные литералы в IRB, и он вернет эквивалент строкового литерала в двойных кавычках:
'\1' "\n"
#=> "\\1\n"
Что, в свою очередь, вы можете использовать в своем коде:
"my string".gsub(/(my )/, "\\1\n")
#=> "my \nstring"
Это не мой минус, поскольку мне нравится более эзотерическая сторона рубина. В этом смысле пространство между ними технически ненужно, например. '\1'"\n"
и если вы действительно хотите расстроить некоторых людей ?\\+?1+?\n
или ?\\<<?1<<?\n
(что почти похоже на последовательность инструкций)
Это может быть полезно для обфускации :) <<
однако это вызовы методов, тогда как соседние литералы обрабатываются на этапе парсера.
Они абсолютно таковы, потому что парсер не допускает буквального смежности символов, все это просто для развлечения и понимания языка. Прямо как ?????:??
.
Самый простой вариант — использовать две обратные косые черты для обратной ссылки
"my string".gsub!(/(my )/, "\\1\n")
. В вашем простом примере вы можете использовать взгляд назад."my string".gsub!(/(?<=my )/, "\n")
. Вы также можете смешивать одинарные и двойные кавычки, используя обратную ссылку"my string".gsub!(/(my )/, '\1'.concat("\n"))