Contar o número de ocorrências de um parexes regex

2

Estou tentando contar o número de ocorrências de uma expressão de parênteses recursivos contendo regex. No meu caso particular, estou procurando contar ocorrências por linha ou por arquivo de (NP *) (VP *) (NP *) . Meu arquivo de exemplo contém (a linha 4 tem um caso recursivo):

$ more mini.example 
    <parse> (NP (NN opposition)) (VP et) (NP gouvernement) (NP (NN opposition)) (VP et) (NP gouvernement) (NP (NN opposition)) (VP et) (NP gouvernement) </parse>
    <parse> (NP (NN opposition)) (XP et) (NP gouvernement) (NP (NN opposition)) (VP et) (NP gouvernement) (NP (NN opposition)) (VP et) (NP gouvernement) </parse>
    <parse> (NP (NN opposition)) (VP et) (NP gouvernement) (NP (NN opposition)) (VP et) (NP gouvernement) </parse>
    <parse> (NP (NN opposition)) (VP et) (NP gouvernement (NP (NN opposition)) (VP et) (NP gouvernement))  </parse>
    <parse> (NP (NN opposition)) (VP et) (FP gouvernement) (NP (NN opposition)) (RP et) (NP gouvernement) </parse>
    <parse> (NP (NN opposition)) (VP et) </parse>
    <parse> (VP et) (NP gouvernement) </parse>

Eu gostaria de ter uma saída assim:

3 1
2 2
2 3
2 4
0 5
0 6

Eu tentei isso:

$ grep -Pon '(?<=\(NP ).*(?=\).*(?<=\(VP ).*(?=\).*(?<=\(NP ).*(?=\))))' mini.example | cut -d : -f 1 | uniq -c | sort -k 1

Mas a saída é:

1 1
1 2
1 4
1 5
1 6

Qual é diferente do desejado. Ele conta exclusivamente a primeira parte do padrão, mesmo se o padrão inteiro não corresponder e a recursão não puder ser verificada. Obrigado por qualquer ajuda.

    
por Nacho 19.08.2016 / 23:32

1 resposta

3

Talvez algo como:

grep -nPo '(?=(\((?:[^()]++|(?1))*\)) (?=\(VP)(?1) (?=\(NP)(?1))\(NP' |
 cut -d: -f1 | uniq -c

Ou seja, ele corresponde a (NP desde que seja o início de um (NP *) (VP *) (NP *) em que usamos a correspondência recursiva PCRE para as partes (...) (a parte (\((?:[^()]++|(?1))*\)) direto da página do manual pcrepattern ).

    
por 20.08.2016 / 00:05