Java Regex:匹配2个冒号之间的字符串

时间:2014-08-04 22:25:27

标签: java regex

我正在尝试编写一个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! :(

似乎第一组“消耗”了第二个冒号并且匹配器找不到我期望的第二个字符串。

有人能指出我正确的方向来解决这个问题吗? 你能否详细说明为什么匹配器“消耗”结肠?

感谢。

3 个答案:

答案 0 :(得分:5)

使用正向前瞻来捕捉以获得重叠的匹配。

(?=(:\\w+:))

注意:您可以参考捕获论坛#1Live Demo

来访问您的匹配结果

答案 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[^:]*:)?");

这适用于所有边缘情况,通过:

  • 从头部和尾部移除输入(包括前导/尾随冒号)
  • 在冒号上分裂,可选地后跟垃圾和另一个冒号
  • “dotall”标记(?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]