1

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

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

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

notInParen

但忽略:

inParen and this

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

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

...但不知道如何找到 [[ ]],四处寻找括号,然后忽略。谢谢!

4

3 回答 3

4

需要一次性完成吗?你可以做:

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

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

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

在第 2 步之后,您有:notInParen.

于 2012-06-05T19:45:12.413 回答
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 将为空。

于 2012-06-05T19:57:51.630 回答
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 ]]
于 2012-06-05T20:07:25.837 回答