正则表达式匹配的是什么

时间:2013-04-23 21:35:07

标签: java 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))

匹配各种表达式,包括:

  

每天一茶匙   1.5毫克
  10毫克1 P.O.夜间

我想要了解的是,每天说1.5 mg和1.5 mg匹配,java正则表达式是否总是与最长的字符串匹配?

3 个答案:

答案 0 :(得分:2)

根据您目前使用的表达式,它实际上不匹配“1.5 mg”,因为定义频率的最后一个组不是可选的。

要用更一般的术语回答你的问题,如果你有一个与正则表达式匹配的字符串,并且该字符串的子字符串也匹配,它完全取决于正则表达式哪一个匹配

例如,使用字符串“foobar”,您将使用正则表达式foo(bar)*匹配整个字符串,但只会将“foo”与正则表达式foo(bar)*?匹配。

如果您想确保最大的字符串始终匹配,请确保在替换时始终先放置较长的元素,例如(foobar|foo)而不是(foo|foobar)。您也可能希望避免使用*?+???之类的延迟重复。

当然,这些只是一些一般性指导原则,彻底测试和重构你的正则表达式,直到你在所有情况下得到预期的结果。

答案 1 :(得分: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

这也会影响群组匹配。

这会导致混淆的一个地方是当人们试图使用正则表达式按字母顺序匹配标识符列表时,执行类似

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

匹配标签。根据输入"<script>Not text in an s tag</script>",第2组将包含"s",而不是"script"

答案 2 :(得分:1)

在这种情况下,如果模式的其余部分与较长的String匹配,则将返回最长的String,而不是最短的String。

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 P.O.夜间