プレイヤー コマンドを解析するために、私はほとんどの場合、splitメソッドを使用して文字列を区切り文字で分割し、残りを一連のif
s またはswitch
es で割り出しました。Javaで文字列を解析するいくつかの異なる方法は何ですか?
15 に答える
私は正規表現がとても好きです。コマンド文字列がかなり単純である限り、手動で解析するのに数ページのコードを必要とする正規表現をいくつか書くことができます。
http://www.regular-expressions.infoをチェックして、正規表現の紹介と Java の具体的な例を確認することをお勧めします。
コマンド インターフェイスをできるだけ寛容にしようとしていると思います。その場合は、次のようなアルゴリズムを使用することをお勧めします。
- 文字列を読み取る
- 文字列をトークンに分割する
- 辞書を使用して同義語を一般的な形式に変換する
- たとえば、「ヒット」、「パンチ」、「ストライク」、「キック」をすべて「ヒット」に変換します。
- 順序付けられていない包括的ベースでアクションを実行する
- 順不同- 「猿の顔を殴る」は「猿の顔を殴る」と同じこと
- 包括的- コマンドが「猿の顔を殴る」であるはずで、「猿を殴る」を提供する場合、これが一致するコマンドの数を確認する必要があります。コマンドが 1 つだけの場合は、このアクションを実行します。コマンドの優先順位を設定するのも良い考えかもしれません。一致した場合でも、最上位のアクションを実行します。
手動で解析するのはとても楽しいです...最初は:)
実際には、コマンドがあまり洗練されていない場合は、コマンド ライン インタープリターで使用されるものと同じように扱うことができます。使用できるライブラリのリストがあります: http://java-source.net/open-source/command-line。Apache Commons CLIまたはargs4j (注釈を使用)から始めることができると思います。それらは十分に文書化されており、使い方は本当に簡単です。それらは自動的に解析を処理し、必要なのはオブジェクト内の特定のフィールドを読み取ることだけです。
より洗練されたコマンドを使用している場合は、正式な文法を作成することをお勧めします。グラマー用のグラフィカル エディター、デバッガー、インタープリターを備えた非常に優れたライブラリがあります。それはANTLR (およびエディターANTLRWorks ) と呼ばれ、無料です:) いくつかの文法例とチュートリアルもあります。
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 には気をつけてください。
...
Sun 自身は、StringTokenizer を使用せず、代わりに String.spilt メソッドを使用することを推奨しています。
また、Pattern クラスも確認する必要があります。
ANTLR/ANTLRWorks にもう一票。ファイルの 2 つのバージョンを作成すると、1 つは実際にコマンドを実行するための Java コードを含み、もう 1 つはそれを含まない (文法だけを含む) 場合、言語の実行可能な仕様が得られます。これは、テストに最適であり、文書化に役立ちます。 、そして移植することにした場合の大きな時間の節約になります。
これがコマンドラインを解析する場合は、Commons Cliを使用することをお勧めします。
Apache Commons CLI ライブラリは、コマンド ライン インターフェイスを処理するための API を提供します。
Java 用のパーサー ジェネレーターであるJavaCCを試してください。
言語を解釈するための多くの機能があり、Eclipse で十分にサポートされています。
@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;
}
テキストに区切り文字が含まれている場合は、メソッドを使用できますsplit
。
テキストに不規則な文字列が含まれている場合は、その形式が異なることを意味する場合は、を使用する必要がありますregular expressions
。
JCommanderはまだテストしていませんが、かなり良いようです。
コマンドの区切り文字列が常に同じ文字列または文字 (";" など) である場合は、StrinkTokenizer クラスを使用することをお勧めします。
ただし、セパレーターが異なる場合や複雑な場合は、正規表現を使用することをお勧めします。これは、1.4 以降、String クラス自体、メソッド分割で使用できます。java.util.regex パッケージの Pattern クラスを使用します。
スペースに対する単純な文字列トークナイザーは機能するはずですが、これを行う方法は本当にたくさんあります。
トークナイザーを使用した例を次に示します。
String command = "kick person";
StringTokenizer tokens = new StringTokenizer(command);
String action = null;
if (tokens.hasMoreTokens()) {
action = tokens.nextToken();
}
if (action != null) {
doCommand(action, tokens);
}
その後、トークンをさらに引数に使用できます。これはすべて、引数にスペースが使用されていないことを前提としています...したがって、独自の単純な解析メカニズムをロールバックしたい場合があります(最初の空白を取得してアクションの前にテキストを使用するか、気にしない場合は正規表現を使用するなど)。スピードヒット)、どこでも使用できるように抽象化するだけです。
split メソッドは、文字列を指定された部分文字列式の配列に分割できますregex
。その引数は 2 つの形式、つまり、split ( String regex
) と split String regex, int limit
() です。実際には、split ( String regex
) は、split (String regex, int limit) を呼び出して達成しますが、制限は 0です。では、limit> 0とlimit <0は何を表しているのでしょうか?
jdkが説明した場合: limit > 0サブ配列の長さが limit まで、つまり、可能であれば、limit-1サブディビジョンであり、サブストリングとして残ります (limit-1 回を除いて、文字は文字列の分割端を持ちます) ;
limit <0は、配列の長さに制限がないことを示します。
limit = 0文字列の末尾の空の文字列は切り捨てられます。
StringTokenizer
class は互換性のためのものであり、従来のクラスが保持されているため、String クラスの split メソッドを使用するようにしてください。リンク参照
言語が単純な場合
動詞名詞
その後、手で分割するとうまくいきます。
より複雑な場合は、ANTLR や JavaCC などのツールを検討する必要があります。
http://javadude.com/articles/antlrtutに ANTLR (v2) のチュートリアルがあり、それがどのように機能するかがわかります。