【问题标题】:How to match several capturing groups, but results not as expected如何匹配多个捕获组,但结果不如预期
【发布时间】:2016-06-16 02:54:16
【问题描述】:

我正在尝试学习 Java 正则表达式。我想将几个捕获组(即j(a(va)))与另一个字符串(即this is java. this is ava, this is va)进行匹配。我期望输出是:

I found the text "java" starting at index 8 and ending at index 12.
I found the text "ava" starting at index 21 and ending at index 24.    
I found the text "va" starting at index 34 and ending at index 36.
Number of group: 2

但是,IDE 只输出:

I found the text "java" starting at index 8 and ending at index 12.
Number of group: 2

为什么会这样?有什么我遗漏的吗?

原码:

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("\nEnter your regex:");

        Pattern pattern
                = Pattern.compile(br.readLine());

        System.out.println("\nEnter input string to search:");
        Matcher matcher
                = pattern.matcher(br.readLine());

        boolean found = false;
        while (matcher.find()) {
            System.out.format("I found the text"
                    + " \"%s\" starting at "
                    + "index %d and ending at index %d.%n",
                    matcher.group(),
                    matcher.start(),
                    matcher.end());
            found = true;
            System.out.println("Number of group: " + matcher.groupCount());
        }
        if (!found) {
            System.out.println("No match found.");
        }

运行上面的代码后,我输入了以下内容:

Enter your regex:
j(a(va))

Enter input string to search:
this is java. this is ava, this is va

IDE 输出:

I found the text "java" starting at index 8 and ending at index 12.
Number of group: 2

【问题讨论】:

  • 尝试使用regex101.com
  • 我认为您误解了捕获组的作用。它们不会使正则表达式的其他部分成为可选,因此您的正则表达式仅匹配整个字符串 java
  • 请不要发布从 System.in 读取的问题并对结果进行处理,因为这意味着您可以 a) 轻松调试代码以识别从 System.in 读取的错误或 b ) 对字符串进行硬编码。在这两种情况下,这意味着代码不是一个最小的示例和/或错误的来源可以很容易地缩小范围。这也意味着重现问题需要做更多的工作。

标签: java regex match capturing-group


【解决方案1】:

您的正则表达式只匹配整个字符串java,它不匹配avava。当它匹配java 时,它会将捕获组1 设置为ava,并将捕获组2 设置为va,但它本身并不匹配这些字符串。会产生您想要的结果的正则表达式是:

j?(a?(va))

? 使前面的项目是可选的,因此它将匹配后面的项目而没有这些前缀。

DEMO

【讨论】:

  • 非常感谢您的帮助!!真的很感激!!
【解决方案2】:

你需要正则表达式(j?(a?(va)))

Pattern p = Pattern.compile("(j?(a?(va)))");
Matcher m = p.matcher("this is java. this is ava, this is va");

while( m.find() )
{
    String group = m.group();
    int start = m.start();
    int end = m.end();
    System.out.format("I found the text"
                  + " \"%s\" starting at "
                 + "index %d and ending at index %d.%n",
                  group,
                  start,
                   end);



}

可以看demohere

【讨论】:

    猜你喜欢
    • 2013-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 2019-11-12
    • 1970-01-01
    相关资源
    最近更新 更多