当前位置: 首页 > 面试题库 >

Java正则表达式匹配器未找到所有可能的匹配项

施恩
2023-03-14
问题内容

从那时起,我一直在TutorialsPoint上查看代码,此后一直困扰着我……看一下这段代码:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches
{
    public static void main( String args[] ){

      // String to be scanned to find the pattern.
      String line = "This order was placed for QT3000! OK?";
      String pattern = "(.*)(\\d+)(.*)";

      // Create a Pattern object
      Pattern r = Pattern.compile(pattern);

      // Now create matcher object.
      Matcher m = r.matcher(line);
      while(m.find( )) {
         System.out.println("Found value: " + m.group(1));
         System.out.println("Found value: " + m.group(2));
         System.out.println("Found value: " + m.group(3));
      }
   }
}

此代码成功打印:

Found value: This was placed for QT300 
Found value: 0
Found value: ! OK?

但是根据正则表达式"(.*)(\\d+)(.*)",为什么它不返回其他可能的结果,例如:

Found value: This was placed for QT30 
Found value: 00
Found value: ! OK?

要么

Found value: This was placed for QT 
Found value: 3000
Found value: ! OK?

如果此代码不适合这样做,那么我该如何编写一个可以找到所有可能匹配项的代码?


问题答案:

这是因为的贪婪,*随之而来的是回溯。

字串:

This order was placed for QT3000! OK?

正则表达式:

(.*)(\\d+)(.*)

我们都知道那.*是贪婪的,并且尽可能匹配所有字符。因此,第一个.*匹配所有字符,直到最后一个匹配?,然后按顺序回溯以提供匹配。正则表达式中的下一个模式是\d+,因此它回溯到一个数字。一旦找到数字,就\d+匹配该数字,因为这里满足条件(
\d+ 匹配一个或多个数字)。现在,第一个(.*)捕获This order was placed for QT300,随后的(\\d+)捕获捕获0位于!符号之前的数字。

现在,下一个模式将(.*)捕获剩余的所有字符!<space>OK?
m.group(1)指的是出现在组索引1内的字符,并m.group(2)指代索引2,就像它继续一样。

在这里查看演示。

获得所需的输出。

String line = "This order was placed for QT3000! OK?";
  String pattern = "(.*)(\\d{2})(.*)";

  // Create a Pattern object
  Pattern r = Pattern.compile(pattern);

  // Now create matcher object.
  Matcher m = r.matcher(line);
  while(m.find( )) {
     System.out.println("Found value: " + m.group(1));
     System.out.println("Found value: " + m.group(2));
     System.out.println("Found value: " + m.group(3));
  }

输出:

Found value: This order was placed for QT30
Found value: 00
Found value: ! OK?

(.*)(\\d{2}),按顺序回溯最多两位数以提供匹配。

改变你的模式,

String pattern = "(.*?)(\\d+)(.*)";

要获得类似的输出,

Found value: This order was placed for QT
Found value: 3000
Found value: ! OK?

?* 部队*进行非贪婪的比赛之后。

使用额外的捕获组从单个程序获取输出。

String line = "This order was placed for QT3000! OK?";
String pattern = "((.*?)(\\d{2}))(?:(\\d{2})(.*))";
Pattern r = Pattern.compile(pattern);
      Matcher m = r.matcher(line);
      while(m.find( )) {
         System.out.println("Found value: " + m.group(1));
         System.out.println("Found value: " + m.group(4));
         System.out.println("Found value: " + m.group(5));
         System.out.println("Found value: " + m.group(2));
         System.out.println("Found value: " + m.group(3) + m.group(4));
         System.out.println("Found value: " + m.group(5));
     }

输出:

Found value: This order was placed for QT30
Found value: 00
Found value: ! OK?
Found value: This order was placed for QT
Found value: 3000
Found value: ! OK?


 类似资料:
  • 我试图用python及其正则表达式找到所有可能的单词/标记对或其他嵌套组合。 寻找: 我认为正则表达式也可以找到嵌套的括号单词/标记对,但它不返回它们。我该怎么做?

  • 问题内容: 我正在尝试使用python及其正则表达式查找所有可能的单词/标记对或其他嵌套组合。 寻找: 我认为正则表达式公式也可以找到嵌套的括号单词/标记对,但它不会返回它们。我应该怎么做? 问题答案: 实际上,不可能使用正则表达式来做到这一点,因为正则表达式表达了一种由 正则 语法定义的语言,该语言可以通过非限定性自动机来解决,其中匹配由状态表示;然后要匹配嵌套的括号,您需要能够匹配无限数量的括

  • 问题内容: 当字符串以数字开头时,我需要匹配,然后是一个点,然后是一个空格和1个或多个大写字符。匹配必须发生在字符串的开头。我有以下字符串。 我尝试过的正则表达式是: 它不匹配。一个有效的正则表达式将对这个问题有什么作用? 问题答案: (对不起,我先前的错误。大脑现在坚定地投入了。嗯,也许。) 这有效: 分解: =字符串开头 =一个或多个数字 (之所以转义,是因为它在字符串中,因此) =文字(或者

  • 问题内容: 我从以下格式的文件中获取输入: 现在,我想在我的Java代码中读取int1,int2,int3和int4。我该如何在Java中使用正则表达式匹配。谢谢。 问题答案: 为了避免空值:

  • 问题内容: 我正在尝试在Python 2.6中使用re查找更大系列的数字中的每10位数字系列。 我很容易就能抓住不重叠的比赛,但我希望数字系列中的每场比赛。例如。 在中 我应该得到以下列表: 我已经找到了“超前”的引用,但是我所看到的示例仅显示数字对,而不是较大的分组,而且我无法将其转换为两位数以外的数字。 问题答案: 在前瞻范围内使用捕获组。前瞻捕捉你感兴趣的文本,但是实际匹配在技术上是前瞻之前

  • 当所有组都是可选的时,我在提取组时遇到了问题。 上下文(如果您愿意,可以跳到结尾):这是在将字符串与一堆正则表达式进行最佳匹配并查看哪个表达式具有最多组匹配的上下文中。 例如,我可能有一个潜在的格式; 但我希望用户打错字,或者不包含空格或其他东西。 所以我可以用绳子测试一下 并希望获得组 一个 光盘 1-1 G 而且,对于测试字符串 我想得到   DE   克 下面是我的正则表达式,用于匹配以下可