[英]How to extract data from a string Regex
为什么在这段代码中我必须重复3次正则表达式模式才能找到3个独立的数字? 我只想使用".*(\\\\d{10}+).*"
来查找字符串word
中的所有数字,但是我必须重复3次,这为什么我做错了?
public static void main (String [] args){
String word = " Some random mobile numbers 0546 105 610, 451 518 9675, 54 67892 541";
word = word.replaceAll("\\s+","");
Pattern pat = Pattern.compile(".*(\\d{10}+).*"+".*(\\d{10}+).*"+".*(\\d{10}+).*");
Matcher mat = pat.matcher(word);
while (mat.find()) {
for (int i = 1; i <= mat.groupCount(); i++) {
System.out.println(mat.group(i));
}
}
}
这是因为.*
是贪婪的模式(请参阅Regex Quantifiers ),这意味着它会在仍然匹配的情况下尝试从字符串中尽可能多地食用。 因此,在您的情况下,它将捕获除最后一个数字以外的所有数字。
为了解决这个问题,您应该摆脱完全匹配模式.*
,因为find
已经可以为您提供所有匹配项,并且介于两者之间。
因此,仅使用(\\\\d{10})
应该可以。
public static void main (String [] args){
String word = " Some random mobile numbers 0546 105 610, 451 518 9675, 54 67892 541";
word = word.replaceAll("\\s+","");
Pattern pat = Pattern.compile("(\\d{10})");
Matcher mat = pat.matcher(word);
while (mat.find()) {
for (int i = 1; i <= mat.groupCount(); i++) {
System.out.println(mat.group(i));
}
}
}
@Hesham Attia的答案很简单,可以解决您的问题,仅需更多说明它与原始模式的不同之处。
让我们将索引i
添加到代码的匹配组中:
public static void main(String[] args) throws IOException {
String word = " Some random mobile numbers 0546 105 610, 451 518 9675, 54 67892 541";
word = word.replaceAll("\\s+", "");
Pattern pat = Pattern.compile("(\\d{10})");
Matcher mat = pat.matcher(word);
while (mat.find()) {
for (int i = 1; i <= mat.groupCount(); i++) {
System.out.println("Group-" + i + ": " + mat.group(i));
}
}
}
您将得到结果:
组1:0546105610
第1组:4515189675
组1:5467892541
pattern
的结果是:
组1:0546105610
2组:4515189675
组3:5467892541
实际上,上面带有新pattern "(\\\\d{10})"
的代码等效于以下代码:
public static void main(String[] args) throws IOException {
String word = " Some random mobile numbers 0546 105 610, 451 518 9675, 54 67892 541";
word = word.replaceAll("\\s+", "");
Pattern pat = Pattern.compile("\\d{10}");
Matcher mat = pat.matcher(word);
while (mat.find()) {
System.out.println(mat.group());
}
}
如果您引用Matcher.find(), Matcher.group(), Matcher.groupCount()
的javadoc,则会发现Matcher.find()
方法尝试查找给定模式的下一个匹配子字符串Matcher.group()
返回上一个匹配项,并且Matcher.groupCount()
不包括整个匹配项(即组0),仅包括模式中指定的捕获组。
简而言之,正则表达式引擎的工作方式是它将遍历您的模式与主题子序列,并尝试尽可能地匹配(贪婪模式),现在让我们讨论一下这些模式之间的区别:
您的原始格式 : ".*(\\\\d{10}+).*"+".*(\\\\d{10}+).*"+".*(\\\\d{10}+).*"
和why you need repeat it three times
如果仅给出".*(\\\\d{10}+).*"
,则模式将匹配整个字符串,匹配部分为:
.*
\\\\d{10}+
并进入组1 .*
整个字符串已经用于第一次尝试,并且没有任何样式可以再次匹配,您无法提取出第二个和第三个数字,因此您需要重复将样式分成单独的组。
模式 "(\\\\d{10})"
:
每次调用mat.find()
,它将匹配一个数字序列,将其放入组1并返回,然后可以从组1中提取结果,这就是为什么组索引始终为1的原因
模式 "\\\\d{10}"
:
与模式2相同,但不会将匹配结果放入组1,因此您可以直接从mat.group()
获得结果,实际上是组0。
真正的问题是您正在使用Pattern
,因为它需要大量代码,因此容易出错。 这是您在1条简单的代码行中的操作方法:
String[] numbers = word.replaceAll("[^\\d,]", "").split(",");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.