Java - 在两个字符串之间获取所有字符串的最佳方法?(正则表达式?

2022-09-01 04:05:33

这个问题已经困扰了我很长时间了,但本质上我正在寻找最有效的方法来抓取两个字符串之间的所有字符串。

几个月来,我一直在这样做的方式是通过使用一堆临时索引,字符串,子字符串,它真的很混乱。(为什么Java没有这样的本机方法?String substring(String start, String end)

假设我有一个字符串:

abcabc [pattern1]foo[pattern2] abcdefg [pattern1]bar[pattern2] morestuff

最终目标是输出 和 。(稍后将添加到JList中)foobar

我一直在尝试将正则表达式纳入其中,但没有成功。我尝试过使用 's 和 ' 的语法,但我不认为这是我的意图,特别是因为只需要一个参数来拆分。.split()*..split()

否则,我认为另一种方法是使用Pattern和Matcher类?但我对适当的程序真的很模糊。


答案 1

您可以构造正则表达式来为您执行此操作:

// pattern1 and pattern2 are String objects
String regexString = Pattern.quote(pattern1) + "(.*?)" + Pattern.quote(pattern2);

这会将 和 视为文字文本,并且模式之间的文本将在第一个捕获组中捕获。如果你想使用正则表达式,你可以删除Pattern.quote(),但如果你这样做,我不能保证任何事情。pattern1pattern2

您可以通过向 添加标志来添加一些匹配方式的自定义。regexString

  • 如果需要 Unicode 识别不区分大小写的匹配,请在 的开头添加 ,或向 Pattern.compile 方法提供标志。(?iu)regexStringPattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE
  • 如果要捕获内容,即使两个分隔字符串跨行出现,则在 之前添加 ,即 ,或向 Pattern.compile 方法提供 Pattern.DOTALL 标志。(?s)(.*?)"(?s)(.*?)"

然后编译正则表达式,获取 Matcher 对象,循环访问匹配项并将其保存到(或任何 ,由您决定)ListCollection

Pattern pattern = Pattern.compile(regexString);
// text contains the full text that you want to extract data
Matcher matcher = pattern.matcher(text);

while (matcher.find()) {
  String textInBetween = matcher.group(1); // Since (.*?) is capturing group 1
  // You can insert match into a List/Collection here
}

测试代码:

String pattern1 = "hgb";
String pattern2 = "|";
String text = "sdfjsdkhfkjsdf hgb sdjfkhsdkfsdf |sdfjksdhfjksd sdf sdkjfhsdkf | sdkjfh hgb sdkjfdshfks|";

Pattern p = Pattern.compile(Pattern.quote(pattern1) + "(.*?)" + Pattern.quote(pattern2));
Matcher m = p.matcher(text);
while (m.find()) {
  System.out.println(m.group(1));
}

请注意,如果您使用上述方法在此输入之间和其中搜索文本,您将获得一个匹配项,即 .foobarfoo text foo text bar text bar text foo text 


答案 2

这里有一个单行线可以完成所有工作:

List<String> strings = Arrays.asList( input.replaceAll("^.*?pattern1", "")
    .split("pattern2.*?(pattern1|$)"));

细分为:

  1. 删除所有直到 pattern1 的所有内容(要求不以空字符串作为第一项结束)
  2. 在模式 2 和模式 1(或输入结束)之间对输入(非贪婪)进行拆分.*?
  3. 使用实用程序方法生成Arrays.asList()List<String>

下面是一些测试代码:

public static void main( String[] args ) {
    String input = "abcabc pattern1foopattern2 abcdefg pattern1barpattern2 morestuff";
    List<String> strings = Arrays.asList( input.replaceAll("^.*?pattern1", "").split("pattern2.*?(pattern1|$)"));
    System.out.println( strings);
}

输出:

[foo, bar]