2016-11-26 2 views
1

정규식이 https://regex101.com/r/PPbhRn/1입니다. 여기에서 "and"가 캡처되면 위에서 캡처 한 일부 공백을 볼 수 있음을 알 수 있습니다. 그 공백을 제거 할 수있는 방법이 있습니까? 그룹화가 올바르게 캡처 된 경우에만 패턴이 일치하는지 여부를 알고 싶습니다. 내가 제대로 그룹을 캡처 할 수 아니에요정규식 그룹화 및 일치

String validRegex="(((?:[(]* ?[a-z][a-z]+ ?[)]*)|[(]* ?(NOT) (?:[(]* ?[a-z][a-z]+ ?[)]*) ?[)]*)((AND|OR) ((?:[(]* ?[a-z][a-z]+ ?[)]*)|[(]* ?(NOT) (?:[(]* ?[a-z][a-z]+ ?[)]*) ?[)]*))*)"; 

    String formula = "mean AND trip OR (mean OR mango) AND (mean AND orange) OR mango AND (test OR NOT help)"; 
    Pattern p1 = Pattern.compile(validRegex, Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE); 
    final Matcher matcher = p1.matcher(formula); 

    boolean result=MarketMeasureUtil.isValidFormula(formula); 
    System.out.println(result); 

    while (matcher.find()) { 
     System.out.println("Full match: " + matcher.group(0)); 
     for (int i = 1; i <= matcher.groupCount(); i++) { 
      System.out.println("Group " + i + ": " + matcher.group(i)); 
      System.out.println(matcher.group() + "starting at" + "index" + matcher.start()+ "and ending at index" +matcher.end()); 

     } 

, 난 등 "을 의미 및 여행"와 같은 그룹을 캡처 "OR" "의미 또는 망고"필요 .. isValidFormula()는 정규식을 호출합니다. 성냥(). 우리의 경우에는 일치가 잘 작동합니다. 그룹화가 예상대로 작동하지 않습니다.

+4

전체 일치에만 해당 공백이 포함됩니다. 그룹 2는 단지 '와'항상 ... – marekful

+0

나는 ("사과 AND 파인애플 OR (계란) AND (파인애플)와 같은 문자열을 캡처하는 정규식이 필요합니다. 단어와 같은 제약 조건은 술어"AND/OR에 따라야합니다. "그리고 또한 그룹을 부유하게 포착해야합니다. 내가 위의 일치하는 그룹을 제대로 잡을 수없는 정규식을 시도하면 .. 거기에 어떤 방법으로 정렬? @marekful –

+1

질문을 편집하고 시도한 실제 문제와 Java 코드를 보여주십시오. 정규 표현식은 모든 언어/도구마다 약간 씩 다르기 때문에 Regex101 링크를 기반으로 대답해야한다고 생각하지 않습니다. –

답변

0

정규식은이 작업에 적합하지 않습니다. 원하는만큼 중괄호를 추가 할 수 있다면 식의 유효성을 검사 할 수도 있습니다.

당신은 같은 클래스를 사용하여 트리를 구축 파서를 작성해야 :

class Node { 

    boolean[] isAnd = null; 
    Node[] children = null; 
    String literal = null; 

    Node(String literal) { // creator for literals 
     this.literal = literal; 
    } 

    Node(boolean[] isAnd) { // creator for intermediate nodes 
     this.isAnd = isAnd; 
     children = new Node[isAnd.length + 1]; 
    } 

} 

및 방법은 다음과 같을 것이다 :

Node parse(String) throws ParseException { // returns the root 

먼저 당신이 불필요한 중괄호에 제거 할 수 있습니다 왼쪽과 오른쪽을 모두 중괄호로 계산하면 0 레벨 andor (즉, 중괄호 안에없는 값)을 찾고 중간 노드를 만들 수 있습니다. 0 레벨을 찾지 못하면 and s 및 or s 문자열이 리터럴이어야하며 그렇지 않으면 올바르지 않습니다. 그것이 중간 노드 인 경우 0 레벨 andor을 둘러싼 하위 문자열을 사용하여 parse 메서드를 재귀 적으로 호출하여 자식을 추가합니다.

0

DSL을 만든 것처럼 보입니다. "언어"가 복잡하지 않은 경우 파서를 사용하거나 직접 구현하는 것을 고려해야합니다.

나는 단지 OR과 AND 연산을 평가한다고 가정합니다. 이것은 AND (곱하기)가 OR (덧셈)보다 우선 순위가 높은 계산기의 코드와 매우 유사합니다. 그러므로 당신은 당신 자신의 것을 구현할 수 있습니다. 먼저 문을 토큰 화하고 유효성을 검사 할 수는 있지만 정규 표현식을 사용하여 두 문법을 동시에 처리하지는 마십시오. 검증 만이 유일한 목적이라면 여기서 끝낼 수 있습니다. 다음 표현식을 평가해야하는 경우 토큰 (예 : 왼쪽 피연산자는 왼쪽 리프, AND 피연산자는 오른쪽 리프)을 사용하여 이진 트리를 만들고 문법을 적용하여 표현식을 평가할 수 있습니다.

+0

아니요. 그냥 표현식의 유효성을 검사해야합니다. 평가하지 않으려 고합니다. 나는 "(사과 AND (ornage OR 키위))"와 같은 패턴을 필요로합니다. regex.matches() 부분은 mw에서 잘 작동합니다. 하지만 undestand 그룹화 할 수없는 메신저 –