1

次のような正規表現があるとします。

\d+\.?\d* (mg |teaspoon |mcg |tablet |units |puffs |tab )*(\d )*(P\.O\. )*((once )*daily|B\.I\.D\.*|(once )*a day|Q\.I\.D\.|nightly|P\.R\.N\.|T\.I\.D\.|every (other )*(day|morning))

次のようなさまざまな表現に一致します。

小さじ 1 杯を 1 日 1 回
1.5 mg
10 mg 1 PO 毎晩

私が理解しようとしているのは、毎日 1.5 mg と 1.5 mg が一致するということです。Java の正規表現は常に最長の文字列に一致しますか?

4

3 に答える 3

2

周波数を定義する最後のグループはオプションではないため、現在使用している式では実際には「1.5 mg」と一致しません。

より一般的な用語で質問に答えるには、正規表現に一致する文字列があり、その文字列の部分文字列も一致する場合、どれが一致するかは完全に正規表現に依存します。

たとえば、文字列「foobar」の場合、regex を使用して文字列全体と一致しますが、foo(bar)*「foo」のみが regex と一致しfoo(bar)*?ます。

(foobar|foo)最大の文字列が常に一致することを確認したい場合は、交互に常により長い要素を最初に配置するようにしてください(foo|foobar)*?また、 、+?、 などの怠惰な繰り返しの使用も避けたいと思うでしょう??

もちろん、これらは一般的なガイドラインにすぎません。すべてのケースで期待される結果が得られるまで、正規表現を徹底的にテストしてリファクタリングしてください。

于 2013-04-23T21:45:59.233 に答える
1

Java正規表現は常に最長の文字列に一致しますか?

いいえ。通常、正規表現ライブラリは、より長い一致を探すためにバックトラックせずに一致を見つけると停止するため、正規表現は常に最も長い文字列と一致するとは限りません。

例えば、

Pattern p = Pattern.compile("a|aa");
Matcher m = p.matcher("aaa");
while (m.find()) { System.out.println(m.group()); }

印刷します

a
a
a

いいえ

aa
a

これは、グループ マッチングにも影響します。

これが混乱を招く 1 つの場所は、人々が正規表現を使用してアルファベット順に識別子のリストを照合しようとしている場合です。

Pattern.compile("<(/?)(a|b|p|pre|s|script)[^>]*>")

タグを一致させます。入力が与えられた場合"<script>Not text in an s tag</script>"、グループ 2 には"s"ではなくが含まれます"script"

于 2013-04-23T21:40:44.660 に答える
1

この場合、パターンの残りの部分が長い文字列と一致すると、最短の文字列ではなく、最長の文字列が返されます。

public static void main(String[] args) {
    String regex = "\\d+.?\\d* (mg |teaspoon |mcg |tablet |units |puffs |tab )(\\d )(P.O. )*((once )daily|B.I.D.|(once )a day|Q.I.D.|nightly|P.R.N.|T.I.D.|every (other )(day|morning))";

    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher("1.5 mg 10 mg 1 P.O. nightly");
    while(m.find()){
        System.out.println(m.group());
    }

}

プリント: 10 mg 1 PO 毎晩

于 2013-04-23T21:44:03.407 に答える