Perl para correspondência com expressões regulares no Terminal?

2

Estou tentando me familiarizar um pouco com Perl para usar expressão regular procura Terminal (Mac ). Agora, eu não estou realmente querendo aprender Perl rigidamente, apenas tentando descobrir como fazer algumas expressões regulares simples.

Mas não consigo descobrir como fazer isso no Terminal:

Gostaria de combinar expressões em várias linhas e usar tags HTML como exemplo. OBSERVE que a tag HTML é apenas um exemplo de algo a combinar e, especificamente, algo que passa por várias linhas. Se a correspondência de HTML com expressões regulares é uma boa ideia ou não, não é o problema. Eu só quero entender a sintaxe de correspondência com o Perl na linha de comando!

Digamos que eu queira combinar toda a tag ul aqui:

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

Eu gostaria de:

  1. Ser capaz de combinar isso em um arquivo e produzir a correspondência para o stdout (não pergunte por que, eu gostaria apenas de entender como funciona: -))
  2. Consiga substituí-lo por outra coisa.

Para correspondência, encontrei algo assim (usando 'start' e 'end' como exemplo aqui de um arquivo de texto simples quando estava testando, mas, por favor, dê o exemplo da tag ul :

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

Isso corresponde a uma parte, mas apenas em uma linha. Surpreendentemente, adicionando os s no final não funcionou para torná-lo "pontal" ou "modo de linha única", ele ainda apenas correspondia a uma linha ...

Para substituir, tentei algo assim:

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

Isso também não funcionou ...

    
por Anders Svensson 24.04.2012 / 23:58

1 resposta

10

Bem, aqui está uma página da Wikipedia para correspondência ou substituição por Perl one liners . Eu fiz isso em Cygwin :

Perl pode se comportar como grep ou como sed.

O /s faz o ponto corresponder à nova linha.

O -0777 faz com que ele aplique a expressão regular à coisa toda, em vez de linha por linha.

\n também pode corresponder à nova linha.

$ 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

Aqui está o outro formulário, -ne com 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 ~
$

Alguns outros exemplos

$ 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 ~
$

Um exemplo de Global para o -ne one (altere "if" para "while"):

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

Para o -pe , basta adicionar o g no final ( /sg ou /gs , mesma coisa):

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

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

Observação- Esta questão contrasta / s e -0777

    
por 25.04.2012 / 02:46