#ruby #string #escaping #ruby-1.9 #tr
#ruby #строка #экранирование #ruby-1.9 #tr
Вопрос:
Для меня есть что-то загадочное в статусе экранирования обратной косой черты в строковом литерале, заключенном в единственную кавычку, в качестве аргумента String#tr
. Можете ли вы объяснить разницу между тремя примерами ниже? Я особенно не понимаю второго. Чтобы избежать осложнений, я использую 'd'
здесь, который не меняет значения при экранировании в двойных кавычках ( "d"
= "d"
).
'\'.tr('\', 'x') #=> "x"
'\'.tr('\d', 'x') #=> "\"
'\'.tr('\d', 'x') #=> "x"
Комментарии:
1.Интересно. И почему
'\rs'.tr('\rs','x')
возвращается\xx
?! Я бы ожидал возвращаемое значениеxxx
. И в примере с документацией"hello".tr('aeiou', '*')
,*
короче, чемaeiou
, так что жеозначает, если to_str короче, чем from_str, он дополняется последним символом, который он имеет в виду? Это ошибка? Это ошибка? Это Супермен? 😀2. @Zabba Это означает, что это
"hello".tr('aeiou', '*#')
то же самое, что"hello".tr('aeiou', '*####')
. 😀3. Какой результат вы ожидаете (пока не выполняйте его, пожалуйста!) от
'\d'.tr('\d','xx)
? Я не ожидаю, что это даст ..4. @Zabba Чего я бы ожидал, так это ‘xx’.
5. Zabba, очевидно, синтаксическая ошибка. 😉
Ответ №1:
Экранирование в 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
a, на строку замены.