Конвертация между заменой vim и заменой perl pie

Конвертация между заменой vim и заменой perl pie

Итак, у меня есть файл test.txt, который содержит:

home -> range

Если я редактирую файл в vim и запускаю команду, %s/^\(.*\)->\(.*\)$/\2 ::= \1 ;/gона преобразует файл в

range ::= home  ;

что я и хочу. Однако если я запущу

 perl -pi -e 's/^\(.*\)->\(.*\)$/\2 ::= \1 ;/g' test.txt

что, как мне кажется, должно делать то же самое, я не получаю никаких изменений - может кто-нибудь сказать мне, что пошло не так? Я подозреваю, что что-то нужно экранировать, но я перепробовал все возможные комбинации экранирования... плюс я хотел бы узнать некоторые общие правила преобразования между двумя форматами...

решение1

В Perl нельзя экранировать скобки захвата, также принято использовать $1,$2 вместо \1,\2 для переменных захвата.

perl -pi -e 's/^(.*)->(.*)$/$2 ::= $1 ;/g' test.txt

Это печальный факт жизни, чторегулярные выражения(RE), используемые во многих распространенных инструментах (vim, sed, awk, perl), все немного отличаются. Некоторые инструменты имеют возможность использовать Perl RE, POSIX Basic RE (BRE) или POSIX Extended RE (ERE).


perldoc perlreесть что сказать о $1vs \1в замещающей части выражения замены

Некоторые люди слишком привыкают писать что-то вроде:

$pattern =~ s/(\W)/\\\1/g;

Это унаследовано для RHS замены, чтобы не шокировать любителей sed, но это грязная привычка. Это потому, что в PerlThink правая часть "s///" является строкой в ​​двойных кавычках. "\1" в обычной строке в двойных кавычках означает control-A. Обычное значение Unix "\1" заложено вместо "s///". Однако, если вы привыкнете делать это, вы навлечете на себя неприятности, если затем добавите модификатор "/e".

Связанный контент