Замените $ {abc} в текстовом файле, используя Perl, но не \ $ {abc} - PullRequest
1 голос
/ 15 июля 2011

Название вроде говорит само за себя.У меня есть текстовый файл (НЕ файл perl), который содержит любое количество заполнителей в нескольких строках и, возможно, несколько в одной строке.Вот пример:

Здравствуйте, $ {first} $ {last}, пожалуйста, посетите нас по адресу http://${host}${context} и обратите внимание на \ $ {variable}.

Мне нужнозаменить все, что похоже на ${...}, но не то, что выглядит \${...}.Поэтому этот пример необходимо преобразовать в:

Здравствуйте, Джон Доу, пожалуйста, посетите нас по адресу http://example.com/foobar и обратите внимание на \ $ {variable}.

MyВ настоящее время выражение выглядит так:

s/([^\\])\$\{\s*([^\}\s]+)\s*\}/$1 . _lookupVar( $2, $varMap )/ge

, где _lookupVar - это функция, которая знает, как вставить правильное значение.У меня есть первый [^\\], чтобы избежать замены последовательностей \${...}, но это означает, что для ${host}${context} заменяется только ${host}.И по разным причинам я не могу действительно превратить ${host}${context} в ${host} ${context}.

Я могу что-то взломать, но мне было интересно, не скучаю ли я по некоторой магии регулярных выражений, которой кто-то знающий мог бы научить меня; -)

Ответы [ 2 ]

4 голосов
/ 15 июля 2011

Используйте отрицательный взгляд за утверждением (?<!\\) вместо отрицательного класса символов [^\\]:

s/(?<!\\)\$\{\s*([^\}\s]+)\s*\}/_lookupVar($1, $varMap)/ge

Класс персонажа потребляет персонажа сразу за $ (в результате вы должны поставить его обратно с $1), в то время как отрицательный взгляд назад просто проверяет, есть ли там \; если нет, сопоставьте шаблон.

1 голос
/ 15 июля 2011

Чтобы разрешить такие случаи, как:

\\${foo}

Вы можете использовать что-то вроде:

s/(?<!\\)(?:\\\\)* \K \${ \s* ([^\s}]+) \s* }/_lookupVar($1, $varMap)/gxe
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...