我正在尝试编写一个Java正则表达式,它将找到2 :
之间的所有字符串。如果字符之间的字符串有空格,行结尾或制表符,则应忽略它。空字符串也会被忽略。 _
没问题!该组可以包括封闭的:
或不包括。
以下是一些测试和预期的组:
"test :candidate: test" => ":candidate:"
"test :candidate: test:" => ":candidate:"
"test :candidate:_test:" => ":candidate:", ":_test:"
"test :candidate::test" => ":candidate:"
"test ::candidate: test" => ":candidate:"
"test :candidate_: :candidate: test" => ":candidate_:", ":candidate:"
"test :candidate_:candidate: test" => ":candidate_:", ":candidate:"
我已经测试了很多正则表达式,这些正在运行:
":(\\w+):"
":[^:]+:"
当2组“共享”冒号时,我仍有问题:
"test :candidate_: :candidate: test" => ":candidate_:", ":candidate:" // OK
"test :candidate_:candidate: test" => ":candidate_:" // ERROR! :(
似乎第一组“消耗”了第二个冒号并且匹配器找不到我期望的第二个字符串。
有人能指出我正确的方向来解决这个问题吗? 你能否详细说明为什么匹配器“消耗”结肠?
感谢。
答案 0 :(得分:5)
答案 1 :(得分:4)
String.split()
怎么样?
String invalidChars = " |\t|\r|\f|\n"; // regex for invalid characters
String testStr = "test :candidate:_test:";
String[] parts = testStr.Split(":");
List<String> results = new ArrayList<String>();
for (String part : parts)
{
if (part.matches(invalidChars) || part.isEmpty()) continue;
results.add(part);
}
results
应包含candidate
和_test
。
答案 2 :(得分:1)
正则表达式替换组合以清理输入,然后拆分可以在一行中完成整个任务:
String[] terms = input.replaceAll("(?s)^.*?:|:[^:]*$", "").split("(?s):([^:]*\\s[^:]*:)?");
这适用于所有边缘情况,通过:
(?s)
使其可以在多行上工作这是一些测试代码:
String[] inputs = {
"foo:target1:bar",
"foo:target1:target2:bar",
"foo:target1:target2:target3:bar",
"foo:target1:junk junk:target2:bar" ,
};
for (String input : inputs) {
String[] terms = input.replaceAll("(?s)^.*?:|:[^:]*$", "").split("(?s):([^:]*\\s[^:]*:)?");
System.out.println(Arrays.toString(terms));
}
输出:
[target1]
[target1, target2]
[target1, target2, target3]
[target1, target2]