Perl для сопоставления с регулярными выражениями в терминале?
Я пытаюсь немного ознакомиться с Perl, чтобы использовать его для поиска по регулярным выражениям в Terminal (Mac). Сейчас я не собираюсь тщательно изучать Perl, а просто пытаюсь выяснить, как сделать несколько простых регулярных выражений.
Но я не могу понять, как это сделать в терминале:
Я хотел бы иметь возможность сопоставлять выражения в несколько строк, и я возьму HTML- теги в качестве примера. ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИЕ, что HTML-тег - это всего лишь пример чего-то, что нужно сопоставить, и, в частности, то, что занимает несколько строк Является ли соответствие HTML регулярным выражениям хорошей идеей или нет - это не проблема. Я просто хочу понять синтаксис сопоставления с Perl в командной строке!
Скажем, я хочу сопоставить весь тег ul здесь:
<ul>
<li>item 1</li>
<li>item 2</li>
</ul>
Я бы хотел:
- Уметь сопоставлять это в файле и выводить совпадение на стандартный вывод (не спрашивайте почему, я просто хотел бы понять, как это работает:-))
- Уметь заменить это чем-то другим.
Для соответствия я нашел что-то вроде этого (используя '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