1

次のスクリプトを検討してください(疑似言語ではまったくナンセンスです):

if (Request.hostMatch("asfasfasf.com") && someString.existsIn(new String[] {"brr", "hrr"}))   {
    if (Requqest.clientIp("10.0.x.x")) {
        somevar = "1";
    }
    somevar = "2";
}
else {
    somevar = "first";
}
string foo = "foo";
// etc. etc.

if-block のパラメータと内容をどのように取得しますか? if ブロックの形式は次のとおりです。

if<whitespace>(<parameters>)<whitespace>{<contents>}<anything>

String.split()の正規表現パターンで使用してみまし^if\s*\(|\)\s*\{|\}\s*たが、これは惨めに失敗します。つまり、問題は) {内側の if ブロックにも}見られ、多くの場所で閉じが見られることです。ここでは、怠惰な拡張も熱心な拡張も機能しないと思います。

だから...これを正規表現で実装するためにここで必要なものへのポインタはありますか?

また、if ブロックのコードなしで残りの文字列を取得する必要があります (コードは から始まりますelse { ...)。解析された部分の長さに関する情報がないため、使用String.split()するのは難しいようです。

私は最初にこれのためにループベースのソリューションを(String.substring()頻繁に使用して)作成しましたが、それは退屈です。代わりにもっと派手なものが欲しいです。正規表現を使用するか、代わりに解析可能な文字列とパターンを取るカスタムの汎用関数 (これ以外にも多くのケースがあります) を作成する必要があります (if<whitespace>(...上記のパターンを考慮してください)。

編集:そうでなければ意味がなかったので、変数の割り当てに変更されました。

4

3 に答える 3

2

正規表現でこれを行うよりも、パーサーを使用 (または作成) する方がはるかに優れています。

正規表現は何かには最適ですが、このような複雑な解析には不十分です。ここでよく聞かれるもう 1 つの厄介な例は、HTML の解析です。これはある程度まではできますが、複雑なものについては、DOM パーサーの方がはるかに優れたソリューションです。

[非常に] 単純なパーサーの場合、必要なのは中かっこ{とを検索する再帰関数で、左中かっこ}に遭遇するたびにレベルを再帰し、右中かっこを見つけるとレベルを上に戻します。次に、各レベルの 2 つの中括弧の間に文字列の内容を格納する必要があります。

于 2010-10-14T13:15:21.107 に答える
1

上記のように、パーサーが必要です。簡単に実装できる (そして書くのが楽しい!) 型の 1 つは、バックトラッキングを使用した再帰降下パーサーです。また、多くのパーサー ジェネレーターが存在しますが、それらのほとんどには学習曲線があります。Java に適したパーサー ジェネレーターの 1 つにJavaCCがあります。

于 2010-10-14T13:44:32.937 に答える
1

通常の文法は「任意の数の開き括弧の後に任意の数の閉じ括弧が続く」ようなものと一致できないため、通常の言語は機能しません。そのためには、文脈自由文法が必要になります。

Java 用の文脈自由文法パーサーまたは正規表現を正規表現ではなくする正規表現拡張機能を使用しない限り、ループベースのソリューションはおそらく最も優れたソリューションです。

于 2010-10-14T13:10:59.863 に答える