8

PHPで次の形式(EBNF、これが正しいことを願っています)で文字列を解析しようとしています。

<exp>      ::= <base>[{<modifier>["!"]"("<exp>")"}]
<base>     ::= <role>[{<modifier><role>}]
<modifier> ::= "&" | "|"
<role>     ::= ["!"]<str>[","<str>]

<str>通過する文字列はどこにありますか[a-zA-Z0-9\-]+

以下は、解析する必要のあるパターンの例です。

token1
token1&token2
token1|(token2&!token3)
(token1&token2)|(token3&(token4|(!token5,12&token6)))
!(token1&token2|(token3&!token4))|token5,12

私は常に4つのグループを与える正規表現パターンを書き込もうとしています。

  1. 左端<expression>。上記の例から、これは次のようになります。
    • token1
    • token1
    • token1
    • token1&token2
    • token1&token2|(token3&!token4)
  2. 存在した場合["!"]。つまり
    • null
    • null
    • null
    • null
    • !
  3. <modifier>次の(<expression>もしあれば)。これは:
    • null
    • &
    • |
    • |
    • |
  4. パターンの残り。
    • null
    • token2
    • token2&!token3
    • token3&(token4|(!token5,12&token6))
    • token5,12

最初の式にsが含まれていない場合は、これを解析できます<modifier>

^\(?(!?)([a-zA-Z0-9\-]+)\)?([&|]?)(.*)$

私はこの時点で立ち往生しています。ルックアラウンドを使用してみましたが、すべてのブラケットのバランスが取れているときにグループが確実にキャプチャされるようにする方法がわかりません。これはRegExで実現できますか、それともループなどを使用してコードを記述してこれを行う必要がありますか?

4

1 に答える 1

1

私の知る限り、それは不可能です。

文脈自由文法 (EBNF はこのタイプの文法 - タイプ 2 文法用) を持っていますが、これは正規表現 (通常の文法 - タイプ 3 文法用) では解析できません。

http://en.wikipedia.org/wiki/Chomsky_hierarchy

ここで処理できない例: 開始括弧の数 - これらの数ごとに 1 つの正規表現しか記述できません (ただし、無限に存在する可能性がありますよね?)。そうしないと、一致する数が閉じ括弧は同じです。+量指定子 ( 、*など)を持つ正規表現の特定の部分によって計算された文字数を数える方法はありません。

于 2012-07-07T20:54:21.797 に答える