在不紧邻数字的特定单词之后搜索数字

时间:2018-07-05 08:16:25

标签: java regex

我正在尝试使用一种模式来搜索字符串中的邮政编码。我无法使其正常工作。

inputLine的示例为

What is the weather in 75042?

我要用于模式的是

public String getZipcode(String inputLine) {

        Pattern pattern = Pattern.compile(".*weather.*([0-9]+).*");
        Matcher matcher = pattern.matcher(inputLine);

        if (matcher.find()) {

            return matcher.group(1).toString();
        }

        return "Zipcode Not Found.";

    }

如果我只希望获得75002,我需要更改什么?这只会输出数字2的最后一位。我非常困惑,我不完全了解Pattern类的Javadocs。

6 个答案:

答案 0 :(得分:5)

原因是因为.*与前几位数字匹配,并且只剩下一个供您的捕获组使用,所以您必须将其丢弃

可以在这里使用更简单的模式:\D+(\d+)\D+表示

  • 一些非数字\D+,然后一些数字捕获(\d+),然后一些非数字\D+
public String getZipcode(String inputLine) {
    Pattern pattern = Pattern.compile("\\D+(\\d+)\\D+");
    Matcher matcher = pattern.matcher(inputLine);

    if (matcher.find()) {
        return matcher.group(1).toString();
    }
    return "Zipcode Not Found.";
}

Workable Demo

答案 1 :(得分:4)

您的正则表达式(\ s)中缺少空格。您可以根据数据使用\ s *或\ s +

Pattern pattern = Pattern.compile("weather\\s*\\w+\\s*(\\d+)");
Matcher matcher = pattern.matcher(inputLine);

答案 2 :(得分:4)

问题在于中间的.*过于贪婪,吞噬了7500。一个简单的解决方法是在正则表达式前添加一个空格:.*weather.* ([0-9]+).*甚至使用\\s。但是最好是使用.*?的非贪婪版本,因此regexp应该为.*weather.*?([0-9]+).*

答案 3 :(得分:3)

您的.*weather.*([0-9]+).*模式使用第一个.*抓取整行,并回溯以找到weather,如果找到它,则抓取单词末尾的行部分与后续的.*模式对齐并再次回溯以找到最后一位,由于一位数字满足[0-9]+模式,因此唯一一位存储在捕获组1中。最后一个.*仅消耗该行的结尾。

您可以仅使用".*weather.*?([0-9]+).*"(使第二个.*变得懒惰)来解决此问题,但是由于您使用的是Matcher#find(),因此可以使用更简单的正则表达式:

Pattern pattern = Pattern.compile("weather\\D*(\\d+)");

在获得匹配项后,用matcher.group(1)检索值。

请参见 regex demo

模式详细信息

  • weather-一个weather
  • \\D*-除数字以外的0多个字符
  • (\\d+)-捕获第1组:一个或多个数字

请参见Java demo

String inputLine = "What is the weather in 75042?";
Pattern pattern = Pattern.compile("weather\\D*(\\d+)");
Matcher matcher = pattern.matcher(inputLine);

if (matcher.find()) {
    System.out.println(matcher.group(1)); // => 75042
}

答案 4 :(得分:3)

我认为您只需要\\d+

public String getZipcode(String inputLine) throws Exception {

    Pattern pattern = Pattern.compile("\\d+");
    Matcher matcher = pattern.matcher(inputLine);

    if (matcher.find()) {
        return matcher.group();
    }

    //A good practice is to throw an exception if no result found
    throw new NoSuchElementException("Zipcode Not Found.");

}

答案 5 :(得分:2)

在正则表达式中,没有上限(*,+)的运算符为贪婪

已经提出了完善的解决方案。 我只是添加一个非常接近您的地址,并以更隔离的方式解决该问题:

如果使用正则表达式

".*weather.*?([0-9]+).*" ...而不是...

".*weather.*([0-9]+).*"

...您的解决方案将很好地工作。星号后的“ ”指示正则表达式编译器将星号视为非贪婪。

贪婪意味着消耗尽可能多的字符(从左到右),同时仍然允许正则表达式的其余部分匹配。

非贪婪意味着尽可能少地使用字符,同时仍然允许正则表达式的其余部分匹配。