【问题标题】:Extract overlapping matches using split使用拆分提取重叠匹配
【发布时间】:2012-12-26 18:46:28
【问题描述】:

如何使用 String.split() 从输入中提取重叠匹配项?

例如,如果尝试查找与 "aba" 的匹配项:

String input = "abababa";
String[] parts = input.split(???);

预期输出:

[aba, aba, aba]

【问题讨论】:

  • 您确定不是[ ababa, ababa ] 还是只能重叠一个字符?无论如何,我怀疑你不能用正则表达式来做到这一点。出于兴趣,你为什么要这样做?你会如何拆分cababa
  • 您确定split 是您想要的吗?听起来您更像是在尝试 find 匹配。
  • @PeterLawrey 编辑问题以使其更加清晰。很抱歉没有在问题中添加受追捧的匹配项。

标签: java regex split


【解决方案1】:

String#split 不会给你重叠匹配。因为字符串的特定部分,只会包含在获得的数组的唯一索引中,而不包含在两个索引中。

您应该在这里使用PatternMatcher 类。 你可以使用这个正则表达式:-

Pattern pattern = Pattern.compile("(?=(aba))");

并使用Matcher#find方法获取所有重叠匹配,并打印group(1)

上面的正则表达式匹配每个空字符串,然后是aba,然后只打印第一个捕获的组。现在由于look-ahead零宽度 断言,所以它不会消​​耗匹配的字符串。因此,您将获得所有重叠的匹配项。

String input = "abababa";
String patternToFind = "aba";

Pattern pattern = Pattern.compile("(?=" + patternToFind + ")");
Matcher matcher = pattern.matcher(input);

while (matcher.find()) {
    System.out.println(patternToFind + " found at index: " + matcher.start());
}

输出:-

aba found at index: 0
aba found at index: 2
aba found at index: 4

【讨论】:

  • 您为什么要创建一个群组?像往常一样,您使用的代码/复杂性过多。这是给您的挑战:如果您消除组并简化代码,我会接受这个答案。
  • @Bohemian。您可以删除该组,然后打印aba 而不是group 1。该组只不过是您匹配的模式。你知道的。
  • @Bohemian.. 你去吧。编辑删除组。​​
  • @Bohemian.. 我不得不这么说,但你不使用capture group 的理由并不那么强大。如果没有 Capture 组,Regex 的一半功能就会丢失。在此示例中不需要它,也不能证明它根本不需要。例如,假设我说你要找出所有数字后跟#,以及此字符串中# 之后的字符-"asf234#afl234#sdf",你将如何实现这一目标?当您想根据某种模式提取目标字符串的某些部分时,捕获组是必需的。
  • 像上面的例子一样,你只需使用模式 - (\d)#(.),然后提取两个捕获组。就人类可读性而言,我认为这根本不会受到影响。阅读捕获组不是什么,必须如此强调。这在正则表达式中很常见。
【解决方案2】:

我会使用 indexOf。

for(int i = text.indexOf(find); i >= 0; i = text.indexOf(find, i + 1))
   System.out.println(find + " found at " + i);

【讨论】:

  • 我真的很喜欢简洁,但我想要一个基于正则表达式的解决方案。这可以修改为使用正则表达式来查找模式吗?
  • 您可以使用 Rohit Jain 的解决方案。
【解决方案3】:

这不是split() 的正确用法。来自javadocs

围绕给定正则表达式的匹配拆分此字符串。

在我看来,您不是在尝试拆分字符串,而是在字符串中查找正则表达式的所有匹配项。为此,您必须使用Matcher,以及一些在Matcher 上循环的额外代码来查找所有匹配项,然后创建数组。

【讨论】:

  • 正则表达式需要一些技巧才能与 Matcher 一起使用(零宽度环视)。
猜你喜欢
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 2018-03-22
  • 1970-01-01
  • 2013-05-31
相关资源
最近更新 更多