如果我有一个像这样的字符串(来自Wiki标记)我需要用Java解析:
this link (is [[ inParen ]] and) (this) one is [[ notInParen ]]
我想使用正则表达式来提取[[]]中的文本,但是如果它们在括号内则不能。例如,在上面的示例中,它应该返回:
notInParen
但忽略:
inParen and this
...因为它们在括号内。我可以分别找到括号和括号没问题:
.*\(.*?\).* and .*?\[\[(.*?\]\].*
...但无法弄清楚如何找到[[]],四处寻找括号,并忽略。谢谢!
答案 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 ]]