Java字符串与正则表达式分开,忽略括号中的内容

时间:2014-05-02 11:53:39

标签: java regex

我想将" word1 AND word2 OR(word3 AND(word4 OR word5))和word6" " AND&分开#34; 仅在括号外得到:" word1" " word2 OR(word3 AND(word4 OR word5))" " word6"

请注意,括号块可以包含许多其他括号的块。

我已经完成了一些研究,并且我发现了一个与我想要的相反的正则表达式:(?:[^AND(]|\([^)]*\))+这个正则表达式选择了所有的东西,但是" AND"在括号外。我也尝试了前瞻和后视,但没有成功。

有没有办法做我用正则表达式问的问题?

由于

2 个答案:

答案 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)

考虑为此任务创建自己的解析器(它并不复杂)。

  1. 对字符串字符进行迭代,以找到无法从中删除AND的范围。创建将计算嵌套级别的变量。当您找到(时会提高此级别,并在找到)时减少此级别。
    • 如果您找到(并且您将级别从0更改为1,那么它就是范围的开始,
    • 如果您找到),并且您将关卡从1更改为0,那么它就是范围的结束。
  2. 在字符串中找到AND的位置(indexOf(data,fromIndex)在这里可能会有所帮助)并检查它是否超出了您不应该分割的范围。
  3. 当您拥有所有职位时,您应该从start,position创建子字符串,然后将start更新为positoon+"AND".length()之后。在此之后尝试子串下一部分。
  4. 在第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);