Java – 在两个字符串之间获取所有字符串的最佳方法? (正则表达式?)
这个问题一直困扰着我很长一段时间,但基本上我正在寻找最有效的方法来获取两个字符串之间的所有字符串。
我已经做了好几个月的方式现在是通过使用一堆临时索引,字符串,子串,它真的很乱。 (为什么Java没有本地方法,如String substring(String start, String end)
?
说我有一个字符串:
abcabc [pattern1]foo[pattern2] abcdefg [pattern1]bar[pattern2] morestuff
最终目标是输出foo
和bar
。 (后来被添加到JList中)
我一直试图在.split()
加入正则表达式,但还没有成功。 我尝试使用*
和s语法.
但我不认为这是我的意图,特别是因为.split()
只需要一个参数来分割。
否则我认为另一种方法是使用Pattern和Matcher类? 但我对适当的程序非常模糊。
您可以构造正则表达式来为您执行此操作:
// pattern1 and pattern2 are String objects String regexString = Pattern.quote(pattern1) + "(.*?)" + Pattern.quote(pattern2);
这会将pattern1
和pattern2
视为文字文本,并且在第一个捕获组中捕获模式之间的文本。 如果你想使用正则表达式,你可以删除Pattern.quote()
,但如果你这样做我不保证。
您可以通过向regexString
添加标志来添加一些关于匹配应该如何进行的自定义。
- 如果你想要Unicode感知的不区分大小写的匹配,那么在
regexString
的开头添加(?iu)
,或者提供Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE
Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE
标志为Pattern.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 }
测试代码:
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 text foo text bar text bar
搜索foo
和bar
之间的文本,您将获得一个匹配项,即text foo text
。
这是一个完成所有工作的单线程:
List strings = Arrays.asList( input.replaceAll("^.*?pattern1", "") .split("pattern2.*?(pattern1|$)"));
细分是:
- 将所有内容删除到pattern1(作为第一个术语,不需要以空字符串结尾)
- 在pattern2和pattern1(或输入结束)之间的输入(非贪婪
.*?
)上拆分 - 使用实用程序方法
Arrays.asList()
生成List
这是一些测试代码:
public static void main( String[] args ) { String input = "abcabc pattern1foopattern2 abcdefg pattern1barpattern2 morestuff"; List strings = Arrays.asList( input.replaceAll("^.*?pattern1", "").split("pattern2.*?(pattern1|$)")); System.out.println( strings); }
输出:
[foo, bar]
尝试这个:
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 < > <