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

Jus*_*tin 32 java regex string

这个问题一直困扰着我很长一段时间,但基本上我正在寻找最有效的方法来获取两个字符串之间的所有字符串.

我已经做了好几个月的方式现在是通过使用一堆临时索引,字符串,子串,它真的很乱.(为什么Java没有本机方法,比如String substring(String start, String end)

说我有一个字符串:

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

最终目标是输出foobar.(后来被添加到JList中)

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

否则我认为另一种方法是使用Pattern和Matcher类?但我对适当的程序非常模糊.

nha*_*tdh 79

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

// pattern1 and pattern2 are String objects
String regexString = Pattern.quote(pattern1) + "(.*?)" + Pattern.quote(pattern2);
Run Code Online (Sandbox Code Playgroud)

这将处理pattern1pattern2作为文字文本,并且在第一个捕获组中捕获模式之间的文本.Pattern.quote()如果你想使用正则表达式,你可以删除,但如果你这样做我保证.

您可以通过向标记添加标记来添加一些自定义匹配的方法regexString.

  • 如果您希望Unicode识别不区分大小写,请(?iu)在开头添加regexString,或者Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASEPattern.compile方法提供标志.
  • 如果要捕获内容,即使两个分隔字符串出现在行之间,也要在方法(?s)之前添加(.*?),即"(?s)(.*?)"或提供Pattern.DOTALL标志Pattern.compile.

然后编译正则表达式,获取一个Matcher对象,遍历匹配并将它们保存到List(或任何Collection,由你决定).

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
}
Run Code Online (Sandbox Code Playgroud)

测试代码:

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));
}
Run Code Online (Sandbox Code Playgroud)

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

  • @Tajchert:只需将部分(。*?)更改为((s)(。*?)),或在“ Pattern.compile”中添加“ Pattern.DOTALL”标志。 (2认同)

Boh*_*ian 10

这是一个完成所有工作的单线程:

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

细分是:

  1. 将所有内容删除到pattern1(作为第一个术语,不需要以空字符串结尾)
  2. .*?在pattern2和pattern1(或输入结束)之间的输入(非贪婪)上拆分
  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);
}
Run Code Online (Sandbox Code Playgroud)

输出:

[foo, bar]
Run Code Online (Sandbox Code Playgroud)


eli*_*ias 9

试试这个:

String str = "its a string with pattern1 aleatory pattern2 things between pattern1 and pattern2 and sometimes pattern1 pattern2 nothing";
Matcher m = Pattern.compile(
                            Pattern.quote("pattern1")
                            + "(.*?)"
                            + Pattern.quote("pattern2")
                   ).matcher(str);
while(m.find()){
    String match = m.group(1);
    System.out.println(">"+match+"<");
    //here you insert 'match' into the list
}
Run Code Online (Sandbox Code Playgroud)

它打印:

> aleatory <
> and <
> <
Run Code Online (Sandbox Code Playgroud)

  • @ R11G你可以简单地在输出中连接模式变量,或者移动括号以包含模式:`"("+ Pattern.quote(pat1)+".*?"+ Pattern.quote(pat2)+")" `并通过`m.group(1)`抓住它. (2认同)