在方括号中查找文本,但不在括号中

时间:2012-06-05 19:41:48

标签: java regex wikipedia parentheses square-bracket

如果我有一个像这样的字符串(来自Wiki标记)我需要用Java解析:

this link (is [[ inParen ]] and) (this) one is [[ notInParen ]]

我想使用正则表达式来提取[[]]中的文本,但是如果它们在括号内则不能。例如,在上面的示例中,它应该返回:

notInParen

但忽略:

inParen and this

...因为它们在括号内。我可以分别找到括号和括号没问题:

.*\(.*?\).* and .*?\[\[(.*?\]\].*

...但无法弄清楚如何找到[[]],四处寻找括号,并忽略。谢谢!

3 个答案:

答案 0 :(得分:4)

是否需要一次性完成?你可以这样做:

  • 解析字符串并删除括号中包含的所有子字符串。
  • 再次解析结果并使用[[]]获取所有所需的维基百科链接。

这解决了问题并使问题更容易解决。

在第1步之后,您有:this link one is [[ notInParen ]]

在第2步之后,你有:notInParen

答案 1 :(得分:1)

这是一个很好的正则表达式

\(.*?\)|\[\[(.*?)]]

您想要的比赛将在第1组

仅供参考,为了使其更好地执行,您可以通过使用否定字符类替换延迟匹配来最小化回溯。

在Java中,这就变成了

String ResultString = null;
try {
    Pattern regex = Pattern.compile("\\(.*?\\)|\\[\\[(.*?)\\]\\]", Pattern.DOTALL | Pattern.MULTILINE);
    Matcher regexMatcher = regex.matcher(subjectString);
    if (regexMatcher.find()) {
        ResultString = regexMatcher.group(1);
    } 
} catch (PatternSyntaxException ex) {
    // Syntax error in the regular expression
}

请注意,对于交替的第一部分匹配的情况,组1将为空。

答案 2 :(得分:0)

你也可以这样做

String data = "this link (is [[ inParen ]] and) (this) one is [[ notInParen ]]" +
        " this link (is [[ inParen ]] and) (this) one is [[ notInParen ]]";

boolean insideParentheses = false;
int start = 0, end = 0;
for (int i = 0; i < data.length() - 1; i++) {
    if (data.charAt(i) == '(')
        insideParentheses = true;
    if (data.charAt(i) == ')')
        insideParentheses = false;
    // -> [[ and ]] inside Parentheses are not important
    if (!insideParentheses && 
            data.charAt(i) == '[' && data.charAt(i + 1) == '[') {
        start = i;
    }
    if (!insideParentheses && 
            data.charAt(i) == ']' && data.charAt(i + 1) == ']') {
        end = i;
        System.out.println(data.substring(start, end + 2));
    }
}

输出

[[ notInParen ]]
[[ notInParen ]]