5

だから、宿題用のコンパイラスキャナーを書く必要があり、正規表現を使うのは「エレガント」だと思いました。実は、以前はめったに使わなかったのですが、昔のことです。だから私はそれらについてのほとんどのものを忘れて、周りを見回す必要がありました。私はそれらを識別子にうまく使用しました(または少なくとも私はそう思うので、さらにいくつかのテストを行う必要がありますが、今のところすべて問題ないように見えます)が、数字の認識に問題があります。

この関数nextCh()は、入力の次の文字(先読み文字)を読み取ります。ここでやりたいのは、この文字が正規表現と一致するかどうかを確認することです[0-9]*。現在のトークンのフィールドに一致するすべての文字を追加してstrから、このフィールドのint値を読み取ります。「123」などの単一の数値入力を認識しますが、私が抱えている問題は、入力「123 456」の場合、最後のstrが「123456」になり、フィールド「123」と「」を持つ2つの別々のトークンを取得する必要があることです。 456"。「」が一致するのはなぜですか?

private void readNumber(Token t) {
    t.str = "" + ch; // force conversion char --> String
    final Pattern pattern = Pattern.compile("[0-9]*");
    nextCh(); // get next char and check if it is a digit
    Matcher match = pattern.matcher("" + ch);
    while (match.find() && ch != EOF) {
        t.str += ch;
        nextCh();
        match = pattern.matcher("" + ch);
    }
    t.kind = Kind.number;
    try {
        int value = Integer.parseInt(t.str);            
        t.val = value;          
    } catch(NumberFormatException e) {
        error(t, Message.BIG_NUM, t.str);           
    }

ありがとうございました!

PS:以下のコードを使用して問題を解決しました。それでも、正規表現のどこに欠陥があるのか​​を理解したいと思います。

    t.str = "" + ch;
    nextCh(); // get next char and check if it is a number
    while (ch>='0' && ch<='9') {
        t.str += ch;
        nextCh();
    }
    t.kind = Kind.number;
    try {
        int value = Integer.parseInt(t.str);            
        t.val = value;          
    } catch(NumberFormatException e) {
        error(t, Message.BIG_NUM, t.str);           
    }

編集:私の正規表現は識別子の認識にも機能しないことが判明したため(ここでも空白が含まれています)、「ソリューション」と同様のシステムに切り替える必要がありました(多くの条件があります)。正規表現をもう一度勉強する必要があると思います:O

4

3 に答える 3

2

これがあなたの場合に関連しているかどうかは100%わかりませんが、これは次のとおりです。

Pattern.compile("[0-9]*");

アスタリスクがあるため、文字列内の任意の場所にある0 個以上の数字に一致します。「ゼロの数字」の一致なので、スペースが一致すると思います。char が数値であることを確認したい場合は、プラス記号を使用して1 つ以上の に一致させる必要があります。

Pattern.compile("[0-9]+");

または、一度に 1 つの文字しか比較していないため、1 つの数字と一致するだけです。

Pattern.compile("^[0-9]$");
于 2012-10-15T01:13:25.130 に答える
1

matchesメソッドではなく、メソッドを使用する必要がありますfind。ドキュメントから:

一致メソッドは、入力シーケンス全体をパターンと一致させようとします

findメソッドは、入力シーケンスをスキャンして、パターンに一致する次のサブシーケンスを探します。

つまり、を使用するfindと、文字列のどこかに数字が含まれmatchesている場合は一致しますが、使用する場合は文字列全体がパターンと一致する必要があります。

たとえば、次のことを試してください。

Pattern p = Pattern.compile("[0-9]*");
Matcher m123abc = p.matcher("123 abc");
System.out.println(m123abc.matches());  // prints false
System.out.println(m123abc.find());     // prints true
于 2012-10-15T13:20:26.333 に答える
0

次のようなより単純な正規表現を使用します

/\d+/

どこ

  • \d数字を意味します
  • +1つ以上を意味します

コード内:

final Pattern pattern = Pattern.compile("\\d+");
于 2012-10-15T01:15:54.090 に答える