我想将" word1 AND word2 OR(word3 AND(word4 OR word5))和word6" 与" AND&分开#34; 仅在括号外得到:" word1" " word2 OR(word3 AND(word4 OR word5))" " word6"
请注意,括号块可以包含许多其他括号的块。
我已经完成了一些研究,并且我发现了一个与我想要的相反的正则表达式:(?:[^AND(]|\([^)]*\))+
这个正则表达式选择了所有的东西,但是" AND"在括号外。我也尝试了前瞻和后视,但没有成功。
有没有办法做我用正则表达式问的问题?
由于
答案 0 :(得分:0)
对于Pattern.Compile方法,您可以使用Pattern.DOTALL作为参数。代码示例
import java.util.regex.*;
public class Test
{
public static void main(String[] args)
{
String s="word1 AND word2 OR (word3 AND (word4 OR word5)) AND word6";
String regEx="(?:[^AND(]|\\([^)]*\\))+";
Pattern pattern = Pattern.compile(regEx, Pattern.DOTALL);
Matcher matcher = pattern.matcher(s);
while (matcher.find()) {
System.out.println("Found the text \"" + matcher.group() + "\" starting at " + matcher.start() + " index and ending at index " + matcher.end());
}
}
}
请试一试。
答案 1 :(得分:0)
考虑为此任务创建自己的解析器(它并不复杂)。
AND
的范围。创建将计算嵌套级别的变量。当您找到(
时会提高此级别,并在找到)
时减少此级别。
(
并且您将级别从0
更改为1
,那么它就是范围的开始,)
,并且您将关卡从1
更改为0
,那么它就是范围的结束。AND
的位置(indexOf(data,fromIndex)
在这里可能会有所帮助)并检查它是否超出了您不应该分割的范围。start,position
创建子字符串,然后将start
更新为positoon+"AND".length()
之后。在此之后尝试子串下一部分。在第3点之后,你应该拥有你感兴趣的所有部分。
以下是解析器类的示例,它似乎正在执行您想要的操作。要看它将鼠标悬停在它上面。但在使用之前,请尝试创建自己的实现。
class Parser { private static class Range { private int start, end; public Range(int start, int end) { this.start = start; this.end = end; } boolean isInside(int i) { return start <= i && i <= end; } public int getStart() { return start; } @Override public String toString() { return "Range [start=" + start + ", end=" + end + "]"; } } private List<Range> ranges = new ArrayList<Range>(); private boolean checkIfOutsideRanges(int i) { if (ranges.size() == 0) return true; if (ranges.get(0).getStart() > i) return true; for (Range r : ranges) { if (r.isInside(i)) return false; } return true; }
private List<Range> setUpRanges(String data) { int level = 0; int startOfRange = 0; int i = 0; for (char ch : data.toCharArray()) { if (ch == '(') { level++; if (level == 1) startOfRange = i; } if (ch == ')') { level--; if (level == 0) ranges.add(new Range(startOfRange, i)); } i++; } return ranges; }
public List<String> parse(String data) { String toFind = "AND"; ranges = setUpRanges(data); //find indexes of "AND" we should split on List<Integer> toSplit = new ArrayList<Integer>(); int i = -1; do { i = data.indexOf(toFind, i + 1); if (i != -1 && checkIfOutsideRanges(i)) toSplit.add(i); } while (i != -1);
//split on correct AND indexes List<String> results = new ArrayList<String>(); int start = 0; for (Integer index : toSplit) { results.add(data.substring(start, index)); start = index + toFind.length(); } if (start < data.length()) results.add(data.substring(start)); return results; } }
用法示例
String data = "word1 AND ((word2 AND word3) AND word4) AND word5";
Parser p = new Parser();
for (String s : p.parse(data))
System.out.println(s);