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

home -> range

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

range ::= home  ;

что я и хочу Однако, если я бегу

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

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

1 ответ1

1

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

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

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


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

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

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .