3

次の形式の式を解析する必要があります。

(S(A(B(D xyz))(C m)))

(の量は常に)の量と等しくなりますが、(S)の間に任意の数の開き括弧と閉じ括弧のペアが存在する可能性があります。この場合、(A(B(D xyz))(C m))を抽出したいと思います。ファイルには任意の数の(S)句が含まれる可能性があるため、^(S。*)$のようなパターンマッチングを単純に行うことはできません。

(S)の間の潜在的な開き括弧と閉じ括弧のペアの量を知っていれば、これはそれほど難しいことではありませんが、任意の量の()に一致することを知っている正規表現を作成する方法がわかりません。

正規表現パターンを取得するための助けをいただければ幸いです。前もって感謝します。

4

3 に答える 3

1

純粋な正規表現では、任意の数に一致させることはできません。つまり、正規表現を生成/書き込みするときに不明なカウントを一致させることはできません。正規表現を生成するときに知っている限り、nペアのマッチング(ただし高い)は可能です。nn

于 2012-05-16T16:06:01.760 に答える
1

これは理論的には実行できず、実際には、ネストされた括弧の最大数が事前にわかっている場合にのみ実行できます。その解決策はかなり不快な表現を必要とし、通常は好奇心旺盛な宿題の練習として試みられます。これは、正規表現言語が一致する括弧の問題を解決するのに十分強力ではない理由のより良い説明へのリンクです。

この問題を解決するにはパーサーが必要です。単純な再帰下降構文解析でうまくいきます。上記のリンクにあるウィキペディアの記事には、Cでの実装例があり、比較的簡単に他の言語に翻訳できるはずです。

于 2012-05-16T16:03:01.360 に答える
0

おそらく、レコード降下解析が最善の策でしょう。ただし、(S)のバランスを取りたいだけの場合は、エンジンで再帰を行う正規表現を使用して行うことができます。

それは最も外側のバランスを見つけるでしょう。(S(S))のようにネストすることを検討している場合は、正規表現を実装する関数を再帰的に呼び出して、完全一致の「コア」を渡す必要があります。そして、おそらくその過程で親子構造を作成します。しかし、これが関係している場合は、実際のパーサーが解決策になる可能性があります。

Perl正規表現でどのように解決できるか-

$str = '(some (stuff  (S (A (B (D xyz)) (C m))) the end ) (S extra))';

$regex = qr~
[(]
\s* S \s*
(                   # 1
    (                       # 2
      [(]
      (?:  (?> [^()]+ ) 
        |  (?2)                                         
      )*                                               
      [)]
    )
 |
    [^)]*
)
[)]
~x;

while ($str =~ /$regex/g)
{
    print "found '$1'\n";
}

プリント

found '(A (B (D xyz)) (C m))'
found 'extra'
于 2012-05-16T18:53:59.920 に答える