使用正则表达式查找第一个匹配项

8
我希望能够找到第一次出现m²和它前面的数字,可以是整数或小数。 例如:
"某些文本" 38 m² "某些文本", "某些文本" 48.8 m² "某些文本", "某些文本" 48 m² "某些文本"等等。
我目前所做的是:
\d\d,\d\s*(\m\u00B2)|\d\d\s*(\m\u00B2)

目前这个正则表达式可以找到所有的匹配项,但我想使用findFirst()来进行修复。有没有什么办法可以改进正则表达式部分?


1
请查看此链接:https://dev59.com/cWMk5IYBdhLWcg3w7COX - Gregory Prescott
4个回答

10
要获取第一个匹配项,您只需要在if块中使用Matcher#find()
String rx = "\\d+(?:,\\d+)?\\s*m\\u00B2";
Pattern p = Pattern.compile(rx);
Matcher matcher = p.matcher("E.g. : 4668,68 m² some text, some text 48 m²  etc");
if (matcher.find()){
    System.out.println(matcher.group());
}

请查看 IDEONE演示

请注意,您可以使用可选的非捕获组 (?:..)? 来摆脱备选组。

模式分解:

  • \d+ - 1个或多个数字
  • (?:,\d+)? - 0个或多个逗号后跟着至少1个数字的序列
  • \s* - 0个或多个空格符号
  • m\u00B2 - 平方米。

1
建议:在数字周围添加捕获组,这样可以使用group(1)提取它,并使用DecimalFormat进行解析。 - Andreas
当然可以在数字周围设置一个捕获组,只是原始模式没有包含该组。 - Wiktor Stribiżew

1
一种简单的方法!
description.replaceFirst(@NotNull String regex,
                           @NotNull String replacement)

JAVADoc:使用给定的替换字符串替换此字符串中与给定正则表达式匹配的第一个子字符串。

1

这是我在你的帮助下想出来的 :)(正在进行中,稍后应该会返回BigDecimal值),目前看起来可以工作:

 public static String findArea(String description) {

        String tempString = "";
        Pattern p = Pattern.compile("\\d+(?:,\\d+)?\\s*m\\u00B2");

        Matcher m = p.matcher(description);

        if(m.find()) {
            tempString = m.group();
        }
//remove the m and /u00B2 to parse it to BigDecimal later
        tempString = tempString.replaceAll("[^0-9|,]","");
        System.out.println(tempString);
        return tempString;
    }

0

查找最后一个:

    @Test
public void testFindFirstRegExp() {
    String pattern = ".* (\\d+,\\d+) .*";
    Pattern r = Pattern.compile(pattern);
    String line = "some text 44,66 m² some 33,11 m²  text 11,22 m² some text";
    Matcher m = r.matcher(new StringBuilder(line).reverse().toString());
    String expected = "44,66";
    String actual = null;
    if (m.find()) {
        actual = new StringBuilder(m.group(1)).reverse().toString();
    }
    System.out.println("got first:" + actual);
    Assert.assertEquals(expected, actual);

    m = r.matcher(line);
    expected = "11,22";
    actual = null;
    if (m.find()) {
        actual = m.group(1);
    }
    System.out.println("got last:" + actual);
    Assert.assertEquals(expected, actual);
}

打印:

got first:44,66
got last:11,22

注意:需要时请反转模式,例如:
pattern = ".* (\\d+,\\d+-?) .*"; //reverse for (-?\\d+,\\d+)

但这将按预期工作:

pattern = " (\\-?\\d+,\\d+) ";

你在循环中获取它们全部:

while (m.find()) {
    actual = m.group(1);
    System.out.println("got last:" + actual);
}

会打印:

got last:44,66
got last:33,11
got last:11,22

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接