我正在尝试使用一种模式来搜索字符串中的邮政编码。我无法使其正常工作。
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。
答案 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.";
}
答案 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]+).*"
...您的解决方案将很好地工作。星号后的“ ?”指示正则表达式编译器将星号视为非贪婪。
贪婪意味着消耗尽可能多的字符(从左到右),同时仍然允许正则表达式的其余部分匹配。
非贪婪意味着尽可能少地使用字符,同时仍然允许正则表达式的其余部分匹配。