Обратная косая черта в gsub (экранирование и обратная ссылка) - PullRequest
4 голосов
/ 12 июня 2010

Рассмотрим следующий фрагмент:

puts 'hello'.gsub(/.+/, '\0 \\0 \\\0 \\\\0')

Это печатает ( как видно на ideone.com ):

hello hello \0 \0

Это было очень удивительно, потому что я ожидал увидеть что-то вроде этого:

hello \0 \hello \\0

Мой аргумент заключается в том, что \ является escape-символом, поэтому вы пишете \\, чтобы получить буквальную обратную косую черту, таким образом \\0 - это буквальную обратную косую черту \, за которой следует 0 и т. Д. как gsub интерпретирует это, так может кто-нибудь объяснить, что происходит?

А что мне нужно сделать, чтобы получить замену, которую я хочу выше?

1 Ответ

4 голосов
/ 12 июня 2010

Экранирование ограничено при использовании одинарных кавычек, а не двойных кавычек:

puts 'sinlge\nquote'
puts "double\nquote"

"\0" - это нулевой символ (используется, например, в C для определения конца строки), где как '\0' равно "\\0", поэтому и 'hello'.gsub(/.+/, '\0'), и 'hello'.gsub(/.+/, "\\0") возвращают "hello", но 'hello'.gsub(/.+/, "\0") возвращает "\000".Теперь 'hello'.gsub(/.+/, '\\0') возвращение 'hello' - это попытка ruby ​​иметь дело с программистами, не учитывающими разницу между одинарными и двойными кавычками.На самом деле это не имеет ничего общего с gsub: '\0' == "\\0" и '\\0' == "\\0".Следуя этой логике, что бы вы ни думали об этом, вот как ruby ​​видит другие строки: и '\\\0', и '\\\\0' равны "\\\\0", что (при печати) дает вам \\0.Поскольку gsub использует \x для вставки номера совпадения x, вам нужен способ экранирования \x, который равен \\x, или в его строковом представлении: "\\\\x".

Следовательно, строка

puts 'hello'.gsub(/.+/, "\\0 \\\\0 \\\\\\0 \\\\\\\\0")

действительно приводит к

hello \0 \hello \\0
...