Странное Ruby поведение при замене на \ 'X строку - PullRequest
1 голос
/ 20 апреля 2020

Я генерирую некоторые строки RTF и мне нужен код bd. У меня проблемы с командами sub и gsub.

puts 'abc'.sub('a',"\\'B")  => "bcBbc"

Оператор заменяет цель на 'B' без \ 'и копирует оставшуюся часть строки вперед. Я перепробовал много вариантов, и кажется, что проблема в этом.

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

Спасибо

1 Ответ

2 голосов
/ 20 апреля 2020

С документация Ruby :

Аналогично \&, \', \` и \+ соответствуют специальным переменным, $&, $', $` и $+ соответственно.

И здесь , в документации говорится:

  • $~ эквивалентно :: last_match ;
  • $& содержит полный сопоставленный текст;
  • $` содержит строку перед совпадением;
  • $' содержит строку после совпадения;
  • $1, $2 и т. Д. Содержат сопоставление текста первой, второй и т. Д. c группы захвата;
  • $+ содержит последнюю группу захвата.

Пример:

m = /s(\w{2}).*(c)/.match('haystack') #=> #<MatchData "stac" 1:"ta" 2:"c">
$~                                    #=> #<MatchData "stac" 1:"ta" 2:"c">
Regexp.last_match                     #=> #<MatchData "stac" 1:"ta" 2:"c">

$&      #=> "stac"
        # same as m[0]
$`      #=> "hay"
        # same as m.pre_match
$'      #=> "k"
        # same as m.post_match
$1      #=> "ta"
        # same as m[1]
$2      #=> "c"
        # same as m[2]
$3      #=> nil
        # no third group in pattern
$+      #=> "c"
        # same as m[-1]

Таким образом, \' в строке замены замены имеет особое значение. Это означает «Часть исходной строки после совпадения», которая в данном случае равна "bc".

Так что вместо получения \'Bbc вы получите bcBbc

Поэтому, к сожалению, в этом странном сценарии вам необходимо удвоить - избежать обратной косой черты:

puts 'abc'.sub('a',"\\\\'B")  => "\'Bbc"
...