2

Javaを使用してルールを解析し、RegExを使用して内部を読み取ろうとしましたが、RegExを初めて使用するため、いくつかの問題が見つかりました。

まず、この正規表現を使用して述語を解析しようとします(これが複雑すぎるかどうかはわかりません):、"([a-zA-Z]+)\\(([\\?]?[a-zA-Z0-9]+)?(,[\\?]?[a-zA-Z0-9]+)*\\)"これが完全に間違っていることがわかりました...述語は次のようになります(怠惰すぎて完全な式を書く)p(), p(?a), p(?a,?b,c,?d)、。述語名は文字列(英字のみを含む)である必要があり、引数は英字のみを含む文字列またはで始まる文字列?です。

ここで私が見つけた2つの問題がありますp(a,b,c)

  1. (を使用して)各グループの要素を表示するためのループを実行するMatcherと、結果は、、、、および、のみp(a,b,c)になりますが、どうすればこれも取得できますか?pa,cb
  2. ,グループ内に(コンマ記号)を含めないようにするには、繰り返しにも含める必要があることに注意してください。

もう1つのケースでは、入力p()すると、要素が含まれるグループが取得されたのはなぜnullですか?

これを修正する方法はありますか?

4

3 に答える 3

1

最長のサンプル文字列の「arg」値の 1 つは で?b?、説明と一致していないようです。それを削除すると、正規表現はすべてのサンプルに一致しますが、それでも個々の引数を抽出するという問題が残ります。Java でこれを行う最も簡単な方法は、すべての引数を 1 つの文字列としてキャプチャし、その文字列を分割して個々の引数を分割することです。

@Tomalakが言ったように、あなたの正規表現はかなり良いです。私が間違っていると思う唯一のことは?、最初の引数を表すグループの後です。最初の引数だけでなく、引数文字列全体を制御する必要があります。つまり、最初の引数がなければ、2 番目、3 番目などを探しても意味がありません。これが私がそれを行う方法です:

(?:[?]?[a-zA-Z0-9]+(?:,[?]?[a-zA-Z0-9]+)*)?

これは、何も一致しないか、1 つの引数、またはコンマで区切られた複数の引数に一致しますが、正規表現のように(たとえば),aまたはに一致しません。,?a,bJava 文字列リテラルの形式の完全な正規表現を次に示します。

"([a-zA-Z]+)\\(((?:\\??[a-zA-Z0-9]+(?:,\\??[a-zA-Z0-9]+)*)?)\\)"

述語名はグループ #1 に取り込まれ、引数はグループ #2 に取り込まれます。引数がない場合、グループ #2 には空の文字列 ( ではないnull) が含まれます。それ以外の場合は、コンマで分割することにより、個々の引数を分割できます。

\?ところで、ほとんどのメタ文字はバックスラッシュ ( ) または角括弧 ( )でエスケープできます[?]。両方を行う必要はありません。それが 1 文字だけの場合 (つまり、 のような実際の文字クラスの一部ではない場合[!.?])、バックスラッシュを使用することをお勧めします。Java と同じ文字数であることはわかっていますが、バックスラッシュを使用すると、もう少し自己文書化できると思います。


編集:これが私が使用したコードです:

String[] inputs = { "p()", "p(?a)", "p(?a,?b,c,?d)", "p(a,b,c)" };
Pattern p = Pattern.compile(
    "([a-zA-Z]+)\\(((?:\\??[a-zA-Z0-9]+(?:,\\??[a-zA-Z0-9]+)*)?)\\)");

for ( String s : inputs )
{
  Matcher m = p.matcher(s);
  if ( m.matches() )
  {
    System.out.printf("%nFull match: %s%nPredicate name:%n  %s%n",
                      m.group(), m.group(1));
    String allArgs = m.group(2);
    if (allArgs.length() == 0)
    {
      System.out.println("No arguments");
    }
    else
    {
      System.out.println("Arguments:");
      for (String arg : allArgs.split(","))
      {
        System.out.printf("  %s%n", arg);
      }
    }
  }
}
于 2011-06-13T02:30:17.973 に答える
0

要素 p(a,b,c) を指定すると、ここで 2 つの問題が見つかりました。

  1. 正規表現でそのようなことを (簡単に) 行うことはできません。(Perl では、いくつかのトリックを使用してそれを行うことができます。)
  2. のようなもので(?:,(\w+))

もう 1 つのケースでは、p() を入力すると、要素が null であるグループが取得されたのはなぜですか?

「パラメーター」に一致するはずのグループがまったく一致しないため、定義されていません。これがグループのキャプチャの仕組みです。試合後、必要に応じて鳴き声を選択/フィルタリングできます。

正規表現を1つだけ使用するのではなく、これに適切なパーサーを使用/構築する必要があります。

于 2011-06-12T22:39:36.277 に答える
0

「述語は、次のようなものにする必要があります (完全な式を書くのが面倒です)、p()、p(?a)、p(?a、?b?、c、?d)。」

コメントを追加したかったのですが、ie6 で問題が発生しています。あなたがより良い説明をしてくれれば、私はあなたに解決策を教えます。

あなたが扱っているのはテキストです!もっと贅沢なものとしてそれを白塗りしようとしないでください.
「怠け者」であることは、そのp(), p(?a), p(?a,?b?,c,?d)意味を説明していません。すべてのテキスト文字/記号を完全に理解する必要があります。
正規表現は強力で、非常に困難な場合があります。
正規表現式 (抽象化) は、抽象化から推測できません。

すみません、パラメータがわかりません。投稿を削除します...
(どうやら、削除できないようです。誰かがこれを削除してくれたら、ありがとう!)

于 2011-06-13T00:07:47.270 に答える