Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用正则表达式查找捕获组的所有组合_Java_Regex - Fatal编程技术网

Java 使用正则表达式查找捕获组的所有组合

Java 使用正则表达式查找捕获组的所有组合,java,regex,Java,Regex,如何从正则表达式中获取捕获组的所有组合 给定字符串Max-Michael-van-Mustermann我想生成对(Max)(Michael-van-Mustermann),(Max-Michael)(van-Mustermann)和(Max-Michael-van)(Mustermann) 这应该可以通过模式^(+++)(++)$(其中空格是分隔字符)来实现。但是,由于第一个捕获组贪婪地捕获了Max Michael van,将Mustermann留给第二个捕获组,并终止计算,因为整个字符串已匹配

如何从正则表达式中获取捕获组的所有组合

给定字符串
Max-Michael-van-Mustermann
我想生成对
(Max)(Michael-van-Mustermann)
(Max-Michael)(van-Mustermann)
(Max-Michael-van)(Mustermann)

这应该可以通过模式
^(+++)(++)$
(其中空格是分隔字符)来实现。但是,由于第一个捕获组贪婪地捕获了
Max Michael van
,将
Mustermann
留给第二个捕获组,并终止计算,因为整个字符串已匹配

我尝试使用重叠匹配的解决方案(
(?=)
),但这并没有产生预期的结果(从前面一个接一个地吃掉字符,但仍然像以前一样贪婪)

我试着让第一个捕获组变懒,但这恰恰相反。懒惰和/或贪婪的结合不会产生匹配
(马克斯·迈克尔)(范·穆斯特曼)

据我所知,正则表达式试图将整个字符串放入第一个
+
,无法匹配第二个
+
,并继续释放第一个
+
中的字符以与第二个
+
匹配,直到出现匹配为止(在我的例子中是最后一个空格)我希望正则表达式引擎继续释放字符,直到第一个
+


我的实际问题:
我有一个名称列表作为字符串。我不知道在哪里把他们的名字和姓氏分开。然而,我有另一个相同名字的列表,但是名字和姓氏颠倒了

我的想法是在第一个列表中找到所有捕获组的组合,颠倒它们的顺序,并将它们与第二个列表进行匹配

#第一个列表
马克斯·范马斯特曼
米里亚姆·穆斯特夫劳
艾丽丝·博比娜·查尔斯顿
#第二份名单
van Mustermann Max(van是姓氏的一部分)
穆斯特夫劳·米里亚姆
查尔斯顿·爱丽丝·博比纳(博比纳是名字的一部分)
一些大致需要的代码:

String first = "Max van Mustermann";
String second = "van Mustermann Max";

Pattern pattern = Pattern.compile("^(.+) (.+)$");
Matcher matcher = pattern.matcher(first);
while (matcher.find()) { // This is obviously not correct, it will only find the first match
    String swapped = matcher.group(2) + " " + matcher.group(1);
    if(second.equals(swapped)){
        // Success!
    }
}

这可以在没有正则表达式的情况下解决。正是这个钩子让我调查了这个问题。

好吧,我认为单用一个正则表达式搜索是不可能的。但是,您可以通过一次搜索和一次比较来完成:

String first = "Max van Mustermann";
String second = "van Mustermann Max";

Pattern pattern = Pattern.compile("^(.*)" + Pattern.quote(second) + "(.*)$");
Matcher matcher = pattern.matcher(first + " " + first);
if (matcher.matches()) {
  if ((" " + second + " ").equals(matcher.group(2) + " " + matcher.group(1))) {
    // Success!
  }
}
说明: 我们制作了一个字符串,它是“双倍”的第一个字符串:

马克斯·范马斯特曼马克斯·范马斯特曼

如果第二个字符串只是第一个字符串的旋转副本,则它应与第一个字符串匹配:

Maxvan Mustermann Maxvan Mustermann

然后,我们需要检查双精度字符串上剩余的内容是否等于第二个字符串。我们只需要取结尾的“van Mustermann”并加上开头的“Max”。结果必须等于在两侧附加空格的第二个字符串:

" van Mustermann" + " " + "Max " => " van Mustermann Max "

我发现了一个正则表达式,它几乎完全符合您的要求:

String first = "Alice Bobina Charlston Max van Mustermann Miriam Musterfrau";
Pattern pattern = Pattern.compile("(?<=^(.*)\\G)( ?\\w+)(?= (.*$))");
Matcher matcher = pattern.matcher(first);
while (matcher.find()) {
  System.out.printf("(%s)(%s)%n", matcher.group(1) + matcher.group(2), matcher.group(3));
}
唯一的区别是它将文本分成3组,而不是2组,并且必须手动组合前两组才能得到结果。使用此模式,您的代码将如下所示:

String first = "Max van Mustermann";
String second = "van Mustermann Max";

Pattern pattern = Pattern.compile("(?<=^(.*)\\G)( ?\\w+)(?= (.*$))");
Matcher matcher = pattern.matcher(first);
while (matcher.find()) { 
  String swapped = matcher.group(3) + " " + matcher.group(1) + matcher.group(2);
  if(second.equals(swapped)) {
    // Success!
  }
}
String first=“Max van Mustermann”;
字符串second=“van Mustermann Max”;

Pattern Pattern=Pattern.compile(“(?更新了答案,使用trim()的早期版本可能会给出误报,例如,对于
first=“Maxvan Mustermann”
,使用基本字符串操作不是更简单吗?
String first = "Max van Mustermann";
String second = "van Mustermann Max";

Pattern pattern = Pattern.compile("(?<=^(.*)\\G)( ?\\w+)(?= (.*$))");
Matcher matcher = pattern.matcher(first);
while (matcher.find()) { 
  String swapped = matcher.group(3) + " " + matcher.group(1) + matcher.group(2);
  if(second.equals(swapped)) {
    // Success!
  }
}