37

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

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

假设我有一个字符串:

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

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

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

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

4

3 回答 3

88

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

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

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

您可以通过向regexString.

  • 如果您想要 Unicode 感知的不区分大小写的匹配,(?iu)请在 开头添加regexString,或Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE向方法提供标志Pattern.compile
  • 如果要捕获内容,即使两个分隔字符串跨行出现,请添加(?s)before (.*?), ie"(?s)(.*?)"Pattern.DOTALL向方法提供标志Pattern.compile

然后编译正则表达式,获取一个Matcher对象,遍历匹配并将它们保存到 a List(或 any 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
}

测试代码:

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));
}

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

于 2012-06-29T02:41:53.100 回答
12

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

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

细分是:

  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);
}

输出:

[foo, bar]
于 2012-06-29T02:41:16.660 回答
11

试试这个:

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
}

它打印:

> aleatory <
> and <
> <
于 2012-06-29T02:56:37.117 回答