将正则表达式组与Java匹配

时间:2016-06-08 16:30:59

标签: java regex string regex-group

我试图通过使用群组来分割一行正则表达式,但它没有像我预期的那样工作 我想匹配例如这一行:

实施例。 #1:temp name(this is the data)

还有这个:

实施例。 #2:temp name()

我使用了这个正则表达式:

[\s]*temp[\s]+[\s]*([A-Za-z]+)[\s]*[(]\s*(.*)+[)]\s*[{]\s*

表示:抓取以temp开头的任何内容,然后将第1组放入“名称”,然后抓取括号内的任何内容并将其放入第2组。

但是,组#2始终为空。

这是我获取数据的代码:

Pattern PATTERN = Pattern.compile("[\\s]*temp[\\s]+[\\s]*([A-Za-z]+)[\\s]*[(]\\s*(.*)+[)]\\s*");

Matcher m = PATTERN.matcher("temp name(this is the data)");
m.matches();
String name = m.group(1);
String data = m.group(2); // always empty

我做错了什么?

4 个答案:

答案 0 :(得分:2)

你的模式不匹配,因为它需要一个开放的大括号,但你的输入没有。

忽略这个小问题,主要问题是捕获组+之后的小(.*)+。加号需要.*的一个或更多匹配,并且返回的组是众多的最后匹配。术语.*是贪婪的,因此它会消耗所有内容。再次匹配 的唯一方法是使用 nothing 。因此,第2组的最后匹配为空白。

要解决此问题,请在第2组后删除+

Pattern PATTERN = Pattern.compile("\\s*temp\\s+([A-Za-z]+)\\s*[(]\\s*(.*)[)]\\s*");

另请注意我如何从正则表达式中删除其他不必要的字符,例如单字符字符类 - 即[\\s]\s相同。 \\s+\\s*\\s+完全相同,因为+是贪婪的。

我还删除了尾随的花括号,如果您的输入数据实际上有,则可以恢复它(您的问题显示输入"temp name(this is the data)",没有尾随花括号)。

答案 1 :(得分:1)

你的正则表达式应该是这样的:

Pattern pattern = Pattern.compile("\\s*temp\\s+([A-Za-z]+)\\s*[(]\\s*(.*)[)]\\s*");

您有(.*)+表示.*的一个或多个匹配项。这导致没有被捕获。

测试:

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

public class Example {

    public static void main(String[] args) {

        Pattern pattern = Pattern.compile("\\s*temp\\s+([A-Za-z]+)\\s*[(]\\s*(.*)[)]\\s*");

        Matcher m = pattern.matcher("temp name(this is the data)");
        if(m.matches()) {
            System.out.println(m.group(1));
            System.out.println(m.group(2));
        }
    }
}

输出:

name
this is the data

答案 2 :(得分:0)

[\s]\s

等效

[\s]+[\s]*\s+

等效

[(]\(相同([)][}]相同)

这会使你的正则表达式为:

\s*temp\s+([A-Za-z]+)\s*\(\s*(.*)+\)\s*\{\s*

假设您确实想要匹配temp name(...) {(您的正则表达式正在寻找{,而在您的问题中您没有指定):

(.*)+是你的问题。你说:“匹配任何数字(包括0)聊天,并将它们放入捕获组,至少重复一次”。

Regexp默认是贪婪的(=它们尽可能多地消耗),因此捕获组将首先包含两个括号中的所有内容,然后+将尝试再次匹配整个组,并且将匹配它与""(emtpy字符串)一起实现捕获组的模式。这将完成您的捕获组emtpy。

您想要的是\s*temp\s+([A-Za-z]+)\s*\(\s*(.*)\)\s*\{\s*

答案 3 :(得分:0)

您获得空组的原因是每次在()之间放置一些东西时创建多个捕获组,即使它是嵌套的。

要创建一个组,使其无法捕获,您可以使用?指定它为非捕获组:例如(?:sometest(this is the value we want))只返回一个组,而(sometest(this is the value we want))将返回2个组。

对于您的特定正则表达式,我已经完善并简化了它,因为您拥有不需要的捕获组。

简单的解决方案:

\\s*temp\\s+([A-Za-z]+)\\s*\\(\\s*(.*)\\)\\s*\{\\s*

给出输入:

Ex. #1: temp name(this is the data) {
Ex. #2: temp name() {

$1 = name, $2 = data

注意你的正则表达式包含一个尾随花括号的事实。您可以在没有它的情况下修改正则表达式匹配,这将导致:

\\s*temp\\s+([A-Za-z]+)\\s*\\(\\s*(.*)\\)\\s*

https://regex101.com/r/tD0tO0/1

相关问题