如何有效地找到两个给定子字符串之间的字符串?

How to efficiently find a string between two given substrings?

我有一个字符串,我知道两个唯一的子字符串,哪个在哪​​个之前。找到中间字符串的最有效方法是什么?
现在我正在这样做,效果很好:

middleString = line.split(firstSubstr)[1].split(secondSubstr)[0];

我需要对大量大文件中的每一行都执行此操作,但我觉得这种方式不是很优雅。我想知道是否有另一种方法可以更高效、更优雅地做到这一点。
如果对这一行进行惰性求值,我认为代码会非常高效,但我认为这个表达式并非如此。假设一个由 abc 开头的数百个字符的字符串,第一个子字符串是 "a" 并且 "c" 第二个,代码会在返回 "b".
另一种可能性是编写我自己的方法,逐个字符地迭代原始字符串,直到找到第一个子字符串,然后追加所有字符,直到找到第二个;但我认为应该有比这更简单的方法。

您可以使用 indexOf 而不是拆分来解决此问题,如下所示:

String in = "abcdefghij";
String part1 = "cd";
String part2 = "gh";

int i1 = in.indexOf(part1) + part1.length();  // end of first match
int i2 = in.indexOf(part2, i1);               // start of second match

System.out.println(in.substring(i1, i2));     // "ef"

这是一种使用正则表达式和捕获组的解决方案:

Pattern p = Pattern.compile(Pattern.quote(part1)
                         + "(.*?)"
                         + Pattern.quote(part2));

Matcher m = p.matcher(in);

if (m.find()) {
    System.out.println(m.group(1));  // "ef"
}

关于哪个最快,我认为这取决于多种因素。您使用的是哪个 JRE?是否会一遍又一遍地使用相同的模式(您可以编译一次正则表达式并重新使用它)吗?由于代码只有几行,我建议您简单地试验一下,并在必要时进行分析。


注意您建议的解决方案:

middleString = line.split(firstSubstr)[1].split(secondSubstr)[0];

可能会造成毁灭性的内存占用。看到这个 Q/A:Java String.split memory leak?