3

Я пытаюсь немного ознакомиться с Perl, чтобы использовать его для поиска по регулярным выражениям в Terminal (Mac). Теперь я не очень стараюсь изучать Perl, просто пытаюсь выяснить, как сделать несколько простых регулярных выражений.

Но я не могу понять, как это сделать в терминале:

Я хотел бы иметь возможность сопоставлять выражения в несколько строк, и я возьму HTML- теги в качестве примера. ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИЕ, что HTML-тег - это всего лишь пример чего-то, что нужно сопоставить, и, в частности, то, что идет через несколько строк. Является ли соответствие HTML регулярным выражениям хорошей идеей или нет, это не проблема. Я просто хочу понять синтаксис сопоставления с Perl в командной строке!

Скажем, я хочу сопоставить весь тег ul здесь

<ul>
 <li>item 1</li>
 <li>item 2</li>
</ul>

Я бы хотел:

  1. Иметь возможность сопоставить это в файле и вывести совпадение на стандартный вывод (не спрашивайте почему, я просто хотел бы понять, как это работает :-))
  2. Уметь заменить это чем-то другим.

Для соответствия я нашел что-то вроде этого (используя «начало» и «конец» в качестве примера здесь из простого текстового файла, когда я тестировал, но, пожалуйста, приведите пример для тега ul вместо этого:

perl -wnE 'say $1 if /(start(.*?)end)/' test.txt 

Это соответствует части, но только в одной строке. Удивительно, но добавление s в конце не сработало, чтобы сделать его "точечным" или "однострочным", оно все равно соответствовало одной строке ...

Для замены я попробовал что-то вроде этого:

perl -pe 's/start(.*?)end/replacement text/'s test.txt

Это тоже не сработало ...

1 ответ1

11

Ну, вот страница Википедии для соответствия или замены на Perl one liners. Я сделал это в Cygwin:

Perl может вести себя как grep или как sed.

/s заставляет точку соответствовать новой строке.

-0777 позволяет применять регулярное выражение ко всему, а не к строке.

\n может соответствовать новой строке.

$ echo -e 'a\nb\nc\nd' | perl -0777 -pe 's/.*c//s'

d

user@comp ~
$ echo -e 'a\nb\nc\nd' | perl -pe 's/.*c//s'
a
b

d

Вот другая форма, -ne с print $1

user@comp ~
$ echo -e 'a\nb\nc\nd' | perl -ne 'print $1 if /(.*c)/s'
c
user@comp ~
$ echo -e 'a\nb\nc\nd' | perl -0777 -ne 'print $1 if /(.*c)/s'
a
b
c
user@comp ~
$

Некоторые дополнительные примеры

$ cat t.t
<ul>
 <li>item 1</li>
 <li>item 2</li>
</ul>

$ perl -0777 -ne 'print $1 if /\<ul\>(.*?)\<\/ul>/s' t.t

 <li>item 1</li>
 <li>item 2</li>

user@comp ~
$ perl -0777 -ne 'print $1 if /(.*)/s' t.t
<ul>
 <li>item 1</li>
 <li>item 2</li>
</ul>

user@comp ~
$

Пример Global для -ne one (замените "if" на "while"):

$ echo -e 'bbb' | perl -0777 -ne 'print $1 while /(b)/sg'
bbb

Для -pe просто добавьте g в конце (/sg или /gs , тоже самое):

$  echo -e 'aaa' | perl -0777 -pe 's/a/z/s'
zaa

user@comp ~
$  echo -e 'aaa' | perl -0777 -pe 's/a/z/sg'
zzz

Примечание- Этот вопрос контрастирует / с и -0777

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