1

次のような文字列をトークン化する最も簡単な方法を探しています

       INPUT                       OUTPUT
"hello %my% world" -> "hello ", "%my%", " world"

Javaで。正規表現でこれを達成することは可能ですか? 私は基本的に、区切り文字として「%*%」のようなものを取る String.split() を探していますが、一般的にそうであるように、それは無視されません。

ありがとう

4

4 に答える 4

3

いいえ、あなたが説明した方法でこれを行うことはできません。その理由は――あいまいだ!

あなたは例を挙げます:

「こんにちは %my% 世界」 -> 「こんにちは」、「%my%」、「世界」

% は文字列の前後に付ける必要がありますか?

出力は

「こんにちは」、「%my」、「% world」

または、おそらく出力は

「こんにちは%」、「私の%」、「世界」

あなたの例では、これらのルールのいずれにも従いません。%my% を考え出すと、最初に区切り文字が表示されたに文字列に接続され、次に表示される前に文字列に接続されます。

あいまいさがわかりますか?

そのため、最初に、区切り記号をどこに付けるかについて明確な一連の規則を考え出す必要があります。これを行うと、目的を達成するための簡単な (文字列は不変であるため特に効率的ではありませんが) 方法の 1 つが次のようになります。

  1. String.split()通常の方法で文字列を分割するために使用します
  2. ルール セットに従って、区切り文字を文字列内の必要な場所に再度追加します。
于 2012-12-26T04:07:34.680 に答える
1

%より簡単な解決策は、文字列をsで分割することです。そうすれば、他のすべてのサブシーケンスは%s の間にあります。後で行う必要があるのは、結果を反復処理し、フラグを切り替えて、結果が通常の文字列か%s の間の文字列かを知ることだけです。

空のサブシーケンスをどのように処理するかなど、分割の実装には特別な注意が必要です。入力の開始/終了で空のサブシーケンスを破棄することを決定する実装もあれば、すべての空のサブシーケンスを破棄する実装もあれば、どれも破棄しない実装もあります。

%s がなくなるため、これは必要な正確な出力にはなりません。ただし、実際に必要な場合は簡単に追加できます (必要ないと思います)。

于 2012-12-26T04:14:02.760 に答える
0

可能であれば、より単純な区切り文字を使用してください。String.split()そして、正規表現の代わりに取得できるように、区切り文字として陪審員の「%」を使用しても問題ありません。でもそれが無理なら…

正規表現!を使用してこれを解析できますMatcher。行ごとに 1 つの区切り文字があることがわかっている場合は、行全体を食べるパターンを指定します。

    String singleDelimRegexp = "(.*)(%[^%]*%)(.*)";
    Pattern singleDelimPattern = Pattern.compile(singleDelimRegexp);
    Matcher singleDelimMatcher = singleDelimPattern.matcher(input);

    if (singleDelimMatcher.matches()) {
        String before = singleDelimMatcher.group(1);
        String delim = singleDelimMatcher.group(2);
        String after = singleDelimMatcher.group(3);

        System.out.println(before + "//" + delim + "//" + after);
    }

入力が長く、一連の結果が必要な場合は、Matcher をループで使用します。

String multiDelimRegexp = "%[^%]*%";
    Pattern multiDelimPattern = Pattern.compile(multiDelimRegexp);
    Matcher multiDelimMatcher = multiDelimPattern.matcher(input);

    int lastEnd = 0;
    while (multiDelimMatcher.find()) {
        String data = input.substring(lastEnd, multiDelimMatcher.start());
        String delim = multiDelimMatcher.group();
        lastEnd = multiDelimMatcher.end();
        System.out.println(data);
        System.out.println(delim);
    }
    String lastData = input.substring(lastEnd);
    System.out.println(lastData);

それらをデータ構造に追加すると、解析された入力全体が構築されます。

入力で実行: http://ideone.com/s8FzeW

于 2012-12-26T05:03:45.147 に答える
0

単語間をスペースで区切ってみませんか。その場合、"hello","%my%","world" が返されます。

于 2012-12-26T04:11:32.227 に答える