Perl для сопоставления с регулярными выражениями в терминале?

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

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

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

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

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

Я бы хотел:

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

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

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

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

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

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

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

1 ответ

Решение

Ну, вот страница Википедии для соответствия или замены на 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 ~
$

Пример Глобала для -ne один (изменить "если" на "пока"):

$ 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

Другие вопросы по тегам