0

正規表現パターンが機能しないように見える理由がわかりません。次に例を示します。

String token = "23030G40KT";

Pattern p = Pattern
                .compile("(\\d{3}|VRB)|(\\d{2,3})|(G\\d{2,3})?|(KT|MPS|KMH)");
Matcher m = p.matcher(token);

while(m.find()){
    System.out.println(m.group());
}

それは出力します:

230
30
G40

(ここには表示されていない次の 2 つの空白行があります)

印刷したい:

230
30
G40
KT

空白行なし。何を変更する必要がありますか?

4

4 に答える 4

4

?数量詞を削除できます。

Pattern.compile("(\\d{3}|VRB)|(\\d{2,3})|(G\\d{2,3})|(KT|MPS|KMH)")
于 2013-01-15T23:46:09.530 に答える
1

元の正規表現が機能しない理由は、@Reimus などの他の回答でよく説明されています。ただし、さらに簡素化するお手伝いをしたいと思います。正規表現は複雑に見えますが、分解すると実際には非常に単純です。

元の正規表現が何をするかについて話しましょう。

\\d{3}- 小数点以下 3 桁

|- または

VRB- 「VRB」

|- または

\\d{2,3}- 小数点以下 2 桁または 3 桁

|- または

G\\d{2,3}- "G" の後に 2 桁または 3 桁の小数点が続く

|- または

(KT|MPS|KMH)- 「KT」または「MPS」または「KMH」

つまり、基本的には、たくさんのものを持っているか、一緒にしただけです。それらのいくつかは冗長です (「小数点以下 3 桁」や「小数点以下 2 桁または 3 桁」など)。それらを組み合わせると、グループ化が不要なケースが少なくなります。

この単純な正規表現を使用して同じ結果を得ることができます。

Pattern.compile("G?\\d{2,3}|KT|MPS|KMH|VRB");
于 2013-01-15T23:47:49.603 に答える
1

@Reimeusの回答への補遺、これは正しいものです。

正規表現エンジンが POSIX に従う場合、常に左端の最長の一致を探します。注:最長。

しかし、Java の正規表現は posix ではありません。ここで行うように代替を使用すると、最初に一致が見つかった代替で停止します(すべての代替は左から右に評価されます)。

たとえば、正規表現を試してみると、次のようになります。

cat|catflap

入力に対して:

catflap

Java の正規表現エンジンが一致しcatます。POSIX 正規表現エンジンが一致しcatflapます。

また、POSIX 正規表現エンジンはまれです。

あなたの代替では、(G\d{2,3})? 一致します (空の文字列!) そのため、次の代替は考慮されません。

次の 2 つの空白行も、その代替に一致します。空の一致の場合、正規表現エンジンは入力内の 1 文字をシフトすることに注意してください (そうしないと、無限ループが発生します!)。

于 2013-01-15T23:50:16.690 に答える
0

私はむしろ何かのようなことをしたいです

String token = "23030G40KT";
Pattern p = Pattern.compile("(\\d{3}|VRB)(\\d{2,3})(G\\d{2,3})?(KT|MPS|KMH)");
Matcher m = p.matcher(token);

if(m.matches()) {
    for (int i = 1; i <= m.groupCount(); ++i) {
        System.out.println(m.group(i));
    }
}
于 2013-01-15T23:51:18.730 に答える