使用正则表达式从字符串中提取值

时间:2015-09-24 10:58:09

标签: java regex

我有这个java代码

String msg = "*1*20*11*30*IGNORE*53*40##";
String regex = "\\*1\\*(.*?)\\*11\\*(.*?)\\*(.*?)\\*53\\*(.*?)##";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(msg);
if (matcher.find()) {
    for (int i = 0; i < matcher.groupCount(); i++) {
        System.out.println(matcher.group((i+1)));
    }
}

输出

20
30
IGNORE
40

如何更改正则表达式,忽略IGNORE的字符串? 我想,那些写在那里的东西不是由匹配者找到的。 20,30,40是我需要提取的值的位置,在我的情况下,IGNORE是任何特定于协议的计数器,不需要我

3 个答案:

答案 0 :(得分:1)

您可以使用tempered greedy token确保在IGNORE介于第2和第3个捕获组之间时无法获得匹配:

\\*1\\*(.*?)\\*11\\*(.*?)\\*(?:(?!IGNORE).)*\\*53\\*(.*?)##

demo。在这种情况下,第3组不能包含 IGNORE

当您需要匹配两个不包含某些子字符串的子模式之间的最近窗口时,该标记很有用。

如果您不希望第3组等于IGNORE,请使用否定前瞻:

\\*1\\*(.*?)\\*11\\*(.*?)\\*(?!IGNORE\\*)(.*?)\\*53\\*(.*?)##
                             ^^^^^^^^^^^^

请参阅demo

答案 1 :(得分:1)

始终忽略第3个参数:

只是不要创建捕获(不要使用括号)。

\\*1\\*(.*?)\\*11\\*(.*?)\\*.*?\\*53\\*(.*?)##

忽略位置:

您需要捕捉IGNORE部分就像您正在做的那样,并检查您的循环是否需要忽略:

String msg = "*1*20*11*30*IGNORE*53*40##";
String regex = "\\*1\\*(.*?)\\*11\\*(.*?)\\*(.*?)\\*53\\*(.*?)##";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(msg);
if (matcher.find()) {
    for (int i = 0; i < matcher.groupCount(); i++) {
        if (!matcher.group(i+1).equals("IGNORE")) {
            System.out.println(matcher.group(i+1));
        }
    }
}

DEMO

答案 2 :(得分:0)

拆分*上的输入并将IGNORE视为分隔符的可选部分,首先修剪掉前缀和后缀:

String[] parts = msg.replaceAll("^\\*\\d\\*|##$","").split("(\\*IGNORE)?\\*\\d+\\*");

一些测试代码:

String msg = "*1*20*11*30*IGNORE*53*40##";
String[] parts = msg.replaceAll("^\\*\\d\\*|##$","").split("(\\*IGNORE)?\\*\\d+\\*");
System.out.println(Arrays.toString(parts));

输出:

[20, 30, 40]