Сбросить статус внутри строкового литерала в качестве аргумента `String # tr` - PullRequest
5 голосов
/ 08 мая 2011

Для меня есть что-то загадочное в статусе экранирования обратной косой черты внутри строкового литерала в одной кавычке в качестве аргумента String#tr.Можете ли вы объяснить контраст между тремя примерами ниже?Я особенно не понимаю второй.Чтобы избежать осложнений, я использую здесь 'd', который не меняет смысла при экранировании в двойных кавычках ("\d" = "d").

'\\'.tr('\\', 'x')      #=> "x"
'\\'.tr('\\d', 'x')     #=> "\\"
'\\'.tr('\\\d', 'x')    #=> "x"

1 Ответ

9 голосов
/ 08 мая 2011

Экранирование в tr

Первый аргумент tr работает так же, как группировка символов в скобках в регулярных выражениях.Вы можете использовать ^ в начале выражения для отмены соответствия (заменить все, что не соответствует) и использовать, например, a-f для соответствия диапазону символов.Поскольку он имеет управляющие символы, он также экранируется внутри, поэтому вы можете использовать - и ^ в качестве буквенных символов.

print 'abcdef'.tr('b-e', 'x')  # axxxxf
print 'abcdef'.tr('b\-e', 'x') # axcdxf

Экранирование в строках одинарных кавычек Ruby

Кроме того,при использовании одинарных кавычек, Ruby пытается включить обратную косую черту, когда это возможно, то есть когда он не используется для экранирования другой обратной косой черты или одинарной кавычки.

# Single quotes
print '\\'    # \
print '\d'    # \d
print '\\d'   # \d
print '\\\d'  # \\d

# Double quotes
print "\\"    # \
print "\d"    # d
print "\\d"   # \d
print "\\\d"  # \d

Примеры пересмотрены

Со всем этимпомните, давайте еще раз посмотрим на примеры.

'\\'.tr('\\', 'x')      #=> "x"

Строка, определенная как '\\', становится литеральной строкой \, поскольку первая обратная косая черта экранирует второй.Там нет сюрпризов.

'\\'.tr('\\d', 'x')     #=> "\\"

Строка, определенная как '\\d', становится литеральной строкой \d.Механизм tr, в свою очередь, использует обратную косую черту в литеральной строке для экранирования d.Результат: tr заменяет экземпляры d на x.

'\\'.tr('\\\d', 'x')    #=> "x"

Строка, определенная как '\\\d', становится литералом \\d.Сначала \\ становится \.Тогда \d становится \d, то есть обратный слеш сохраняется.(Это конкретное поведение отличается от двойных строк, где обратный слеш должен был бы быть съеден живым, оставляя только одинокое d)

Буквенная строка \\d затем заставляет tr заменить все символы, которые либоОбратная косая черта или d со строкой замены.

...