如何迭代正则表达式

2022-09-01 07:42:41

假设我有以下字符串:

name1=gil;name2=orit;

我想找到的所有匹配项,并确保整个字符串与模式匹配。name=value

所以我做了以下事情:

  1. 确保整个模式与我想要的匹配。

    Pattern p = Pattern.compile("^((\\w+)=(\\w+);)*$");
    Matcher m = p.matcher(line);
    if (!m.matches()) {
        return false;
    }
    
  2. 迭代模式name=value

    Pattern p = Pattern.compile("(\\w+)=(\\w+);");
    Matcher m = p.matcher(line);
    while (m.find()) {
        map.put(m.group(1), m.group(2));
    }
    

有没有办法用一个正则表达式做到这一点?


答案 1

您可以通过以下方式验证和循环访问具有一个正则表达式的匹配项:

  • 通过在正则表达式的开头放置 a 来确保匹配项之间没有不匹配的字符(例如 ),这意味着“上一个匹配项的结束”。name1=x;;name2=y;\G

  • 通过将字符串的长度与 Matcher.end() 进行比较,检查我们是否在最后一次匹配中到达了字符串的末尾,Matcher.end() 返回最后一个字符匹配后的偏移量。

像这样:

String line = "name1=gil;name2=orit;";
Pattern p = Pattern.compile("\\G(\\w+)=(\\w+);");
Matcher m = p.matcher(line);
int lastMatchPos = 0;
while (m.find()) {
   System.out.println(m.group(1));
   System.out.println(m.group(2));
   lastMatchPos = m.end();
}
if (lastMatchPos != line.length())
   System.out.println("Invalid string!");

现场演示


答案 2

您必须启用多行模式,“^”和“$”才能按预期工作。

Pattern p = Pattern.compile("^(?:(\\w+)=(\\w+);)*$", Pattern.MULTILINE);
while (m.find()) {
    for (int i = 0; i < m.groupCount() - 2; i += 2) {
        map.put(m.group(i + 1), m.group(i + 2));
    }
}

注释(如果正确),您仍然必须循环访问每行的匹配组,并使外部组成为非捕获组 。(?:...)