角かっこ正規表現の発生回数を計算します。

角かっこ正規表現の発生回数を計算します。

再帰角括弧式を含む正規表現の発生回数を計算しようとしています。私の特別な場合は、行またはファイルごとに発生回数を計算しようとしています(NP *) (VP *) (NP *)。私のサンプルファイルには次のものが含まれています(ライン4には再帰的なケースがあります)。

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

私は次の出力が欲しい:

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

私はこれを試しました:

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

ただし、出力は次のようになります。

1 1
1 2
1 4
1 5
1 6

これは必要なものとは異なります。パターン全体が一致せず、再帰を確認できない場合でも、パターンの最初の部分を一意に評価します。助けてくれてありがとう。

答え1

たぶん、次のようなものがあります。

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

つまり、(NPaの始まりであればaと一致し、その部分(直接部分)(NP *) (VP *) (NP *)に対してPCRE再帰マッチングを使用します。(...)(\((?:[^()]++|(?1))*\))pcrepattern のマニュアルページから)。

関連情報