53

プレイヤー コマンドを解析するために、私はほとんどの場合、splitメソッドを使用して文字列を区切り文字で分割し、残りを一連のifs またはswitches で割り出しました。Javaで文字列を解析するいくつかの異なる方法は何ですか?

4

15 に答える 15

19

私は正規表現がとても好きです。コマンド文字列がかなり単純である限り、手動で解析するのに数ページのコードを必要とする正規表現をいくつか書くことができます。

http://www.regular-expressions.infoをチェックして、正規表現の紹介と Java の具体的な例を確認することをお勧めします。

于 2008-08-05T23:54:05.533 に答える
17

コマンド インターフェイスをできるだけ寛容にしようとしていると思います。その場合は、次のようなアルゴリズムを使用することをお勧めします。

  1. 文字列を読み取る
    • 文字列をトークンに分割する
    • 辞書を使用して同義語を一般的な形式に変換する
    • たとえば、「ヒット」、「パンチ」、「ストライク」、「キック」をすべて「ヒット」に変換します。
    • 順序付けられていない包括的ベースでアクションを実行する
    • 順不同- 「猿の顔を殴る」は「猿の顔を殴る」と同じこと
    • 包括的- コマンドが「猿の顔を殴る」であるはずで、「猿を殴る」を提供する場合、これが一致するコマンドの数を確認する必要があります。コマンドが 1 つだけの場合は、このアクションを実行します。コマンドの優先順位を設定するのも良い考えかもしれません。一致した場合でも、最上位のアクションを実行します。
于 2008-08-06T00:42:00.817 に答える
13

手動で解析するのはとても楽しいです...最初は:)

実際には、コマンドがあまり洗練されていない場合は、コマンド ライン インタープリターで使用されるものと同じように扱うことができます。使用できるライブラリのリストがあります: http://java-source.net/open-source/command-lineApache Commons CLIまたはargs4j (注釈を使用)から始めることができると思います。それらは十分に文書化されており、使い方は本当に簡単です。それらは自動的に解析を処理し、必要なのはオブジェクト内の特定のフィールドを読み取ることだけです。

より洗練されたコマンドを使用している場合は、正式な文法を作成することをお勧めします。グラマー用のグラフィカル エディター、デバッガー、インタープリターを備えた非常に優れたライブラリがあります。それはANTLR (およびエディターANTLRWorks ) と呼ばれ、無料です:) いくつかの文法例とチュートリアルもあります。

于 2008-08-30T22:26:00.180 に答える
7

ZorkのJava 移行を見て、次のような単純な自然言語プロセッサ(トークン化または正規表現によって駆動される)に傾倒します (このリンクから)。

    public static boolean simpleNLP(文字列入力行、文字列キーワード[])
    {
        int i;
        int maxToken = キーワード.長さ;
        int へ、から;
        if( inputline.length() = inputline.length()) は false を返します。// 空白行と空行をチェック
        while( から >=0 )
        {
            to = inputline.indexOf(' ',from);
            if( から > 0){
                lexed.addElement(inputline.substring(from,to));
                から=へ;
                while( inputline.charAt(from) == ' '
                && from = keyword.length) { status = true; 壊す;}
            }
        }
        ステータスを返します。
    }

...

プログラマーが Zork を再び検討する理由を与えるものはすべて、私の本では良いことです。Grues には気をつけてください。

...

于 2008-08-06T00:16:25.020 に答える
6

Sun 自身は、StringTokenizer を使用せず、代わりに String.spilt メソッドを使用することを推奨しています。

また、Pattern クラスも確認する必要があります。

于 2008-08-06T16:14:45.460 に答える
6

ANTLR/ANTLRWorks にもう一票。ファイルの 2 つのバージョンを作成すると、1 つは実際にコマンドを実行するための Java コードを含み、もう 1 つはそれを含まない (文法だけを含む) 場合、言語の実行可能な仕様が得られます。これは、テストに最適であり、文書化に役立ちます。 、そして移植することにした場合の大きな時間の節約になります。

于 2008-08-31T01:38:29.890 に答える
4

これがコマンドラインを解析する場合は、Commons Cliを使用することをお勧めします。

Apache Commons CLI ライブラリは、コマンド ライン インターフェイスを処理するための API を提供します。

于 2008-08-31T01:05:38.457 に答える
4

Java 用のパーサー ジェネレーターであるJavaCCを試してください。

言語を解釈するための多くの機能があり、Eclipse で十分にサポートされています。

于 2008-08-31T19:45:45.020 に答える
2

@CodingTheWheelHeresあなたのコード、少しクリーンアップし、日食(ctrl+ shift+ f)を介してここに挿入されます:)

各行の前にある 4 つのスペースを含みます。

public static boolean simpleNLP(String inputline, String keywords[]) {
    if (inputline.length() < 1)
        return false;

    List<String> lexed = new ArrayList<String>(); 
    for (String ele : inputline.split(" ")) {
        lexed.add(ele);
    }


    boolean status = false;
    to = 0;
    for (i = 0; i < lexed.size(); i++) {
        String s = (String) lexed.get(i);
        if (s.equalsIgnoreCase(keywords[to])) {
            to++;
            if (to >= keywords.length) {
                status = true;
                break;
            }
        }
    }
    return status;
}
于 2008-08-06T15:18:18.957 に答える
1

テキストに区切り文字が含まれている場合は、メソッドを使用できますsplit
テキストに不規則な文字列が含まれている場合は、その形式が異なることを意味する場合は、を使用する必要がありますregular expressions

于 2012-11-24T09:17:03.450 に答える
1

JCommanderはまだテストしていませんが、かなり良いようです。

于 2010-08-20T13:59:05.463 に答える
1

コマンドの区切り文字列が常に同じ文字列または文字 (";" など) である場合は、StrinkTokenizer クラスを使用することをお勧めします。

StringTokenizer

ただし、セパレーターが異なる場合や複雑な場合は、正規表現を使用することをお勧めします。これは、1.4 以降、String クラス自体、メソッド分割で使用できます。java.util.regex パッケージの Pattern クラスを使用します。

パターン

于 2008-08-06T15:40:46.917 に答える
1

スペースに対する単純な文字列トークナイザーは機能するはずですが、これを行う方法は本当にたくさんあります。

トークナイザーを使用した例を次に示します。

String command = "kick person";
StringTokenizer tokens = new StringTokenizer(command);
String action = null;

if (tokens.hasMoreTokens()) {
    action = tokens.nextToken();
}

if (action != null) {
    doCommand(action, tokens);
}

その後、トークンをさらに引数に使用できます。これはすべて、引数にスペースが使用されていないことを前提としています...したがって、独自の単純な解析メカニズムをロールバックしたい場合があります(最初の空白を取得してアクションの前にテキストを使用するか、気にしない場合は正規表現を使用するなど)。スピードヒット)、どこでも使用できるように抽象化するだけです。

于 2008-08-05T23:57:02.577 に答える
1

split メソッドは、文字列を指定された部分文字列式の配列に分割できますregex。その引数は 2 つの形式、つまり、split ( String regex) と split String regex, int limit() です。実際には、split ( String regex) は、split (String regex, int limit) を呼び出して達成しますが、制限は 0です。では、limit> 0limit <0は何を表しているのでしょうか?

jdkが説明した場合: limit > 0サブ配列の長さが limit まで、つまり、可能であれば、limit-1サブディビジョンであり、サブストリングとして残ります (limit-1 回を除いて、文字は文字列の分割端を持ちます) ;

limit <0は、配列の長さに制限がないことを示します。

limit = 0文字列の末尾の空の文字列は切り捨てられます。 StringTokenizerclass は互換性のためのものであり、従来のクラスが保持されているため、String クラスの split メソッドを使用するようにしてください。リンク参照

于 2014-05-13T14:13:15.043 に答える
1

言語が単純な場合

動詞名詞

その後、手で分割するとうまくいきます。

より複雑な場合は、ANTLR や JavaCC などのツールを検討する必要があります。

http://javadude.com/articles/antlrtutに ANTLR (v2) のチュートリアルがあり、それがどのように機能するかがわかります。

于 2008-09-16T15:35:53.000 に答える