2014-04-05 3 views
0

정규식을 사용하여 표현식이 포함 된 문자열에서 숫자와 연산자를 가져 오려고합니다. 그것은 숫자를 찾았지만 연산자를 찾지 못했습니다. 문자열의 시작 부분에 매치 (숫자 또는 연산자)가 끝나면 다음 식을 찾으려면 식을 자릅니다.Java Regex 찾기 연산자

String expression = "23*12+11"; 
Pattern intPattern; 
Pattern opPattern; 
Matcher intMatch; 
Matcher opMatch; 

intPattern = Pattern.compile("^\\d+"); 
intMatch = intPattern.matcher(expression); 
opPattern = Pattern.compile("^[-+*/()]+"); 
opMatch = opPattern.matcher(expression); 


while (! expression.isEmpty()) { 
    System.out.println("New expression: " + expression); 
     if (intMatch.find()) { 
      String inputInt = intMatch.group(); 
      System.out.println(inputInt); 
      System.out.println("Found at index: " + intMatch.start()); 
      expression = expression.substring(intMatch.end()); 
      intMatch = intPattern.matcher(expression); 
      System.out.println("Truncated expression: " + expression); 
     } else if (opMatch.find()) { 
      String nextOp = opMatch.group(); 
      System.out.println(nextOp); 
      System.out.println("Found at index: " + opMatch.start()); 
      System.out.println("End index: " + opMatch.end()); 
      expression = expression.substring(opMatch.end()); 
      opMatch = opPattern.matcher(expression); 
      System.out.println("Truncated expression: " + expression); 
     } else { 
     System.out.println("Last item: " + expression); 
     break; 
     } 
    } 

출력은 문자 클래스 내부에 있기 때문에 *, + 특수 문자를 이스케이프 할 필요가 없습니다 지금까지 내가 조사 할 수 있었다으로

New expression: 23*12+11 
23 
Found at index: 0 
Truncated expression: *12+11 
New expression: *12+11 
Last item: *12+11 

입니다. 여기서 뭐가 문제 야?

+0

를 놓쳤다. 별도의 스캐너 및 파서를 작성해야합니다. – EJP

+0

네, 저도 그것에 대해 읽었습니다. 그러나 나는 그것을 어떻게하는지 정말로 모른다. Regex 나는 python과 sed로부터 알고있다. 어쨌든, 정규식이 작동 한 이후로 문제는 무엇입니까? – loxosceles

답변

2

첫째, 디버깅 출력이 혼동입니다. 왜냐하면 두 지점 모두에서 정확히 동일하기 때문입니다. 이러한 ab 접두사로, 구별 뭔가를 추가

System.out.println("a.Found at index: " + intMatch.start()); 

귀하의 문제가 업데이트 된 문자열 모두 매처 (matcher)를 재설정하지 않을 것입니다.에서 모두 가지의 끝에서 당신의 경우-다른 (이후, 단 한 번 또는 경우 - 다른 블록 전체),이 작업을 수행해야합니다

intMatch = intPattern.matcher(expression); 
opMatch = opPattern.matcher(expression); 

마지막으로 한가지 : 당신이 만드는 있기 때문에이 또 다시 Pattern.matcher(s)를 통해 새로운 정규, 당신은 당신의 코드

//"": Unused string so matcher object can be reused 
intMatch = Pattern.compile(...).matcher(""); 

의 상단에, 더미 - 문자열로, 한 번만 정규를 작성하는 것이 좋습니다 각각의 루프에서 다음 reset 팅이 있습니다 반복

(210)

당신은이 같은 재사용 매처 (Matchers) 구현할 수 있습니다

//"": Unused to-search strings, so the matcher objects can be reused. 
Matcher intMatch = Pattern.compile("^\\d+").matcher(""); 
Matcher opMatch = Pattern.compile("^[-+*/()]+").matcher(""); 

String expression = "23*12+11"; 

while (! expression.isEmpty()) { 
    System.out.println("New expression: " + expression); 

    intMatch.reset(expression); 
    opMatch.reset(expression); 

    if(intMatch.find()) { 
     ... 

Pattern *Pattern = ... 

라인 상단에서 제거 할 수 있습니다 하고

*Match = *Pattern.matcher(expression) 

라인 수를 양쪽 if-else 브랜치에서 제거 될 수 있습니다.

+0

잘 작동합니다. 하지만 더미 문자열 부분을 얻지 못했습니다 (상단에서? 내부에서?) 나는 opMatch = opPattern.matcher (expression)를 시작합니다. 두 개의 리셋으로 교체하면 정상적으로 작동합니다. – loxosceles

+0

도움이 되니 기쁩니다. 나는 dummy-string/matcher를 재사용하는 것에 대한 좀 더 많은 정보를 가지고 나의 대답을 업데이트하려고한다. – aliteralmind

1

귀하의 주된 문제점은 고객님 또는 교환 원이 int을 찾았을 때 intMatch 또는 opMatch 만 재 할당한다는 것입니다. 따라서 int 연산자를 찾으면 여전히 이전 버전 expression에서 일치하는 항목을 찾으려고합니다. 그래서 당신은 모두 긍정적 인 경우

intMatch = intPattern.matcher(expression); 
opMatch = opPattern.matcher(expression); 

하지만 어쩌면 대신에 당신의 접근 방식이 개 패턴과 단지의 int 또는 연산자를 찾을 것 하나 정규식을 사용하고 다른 그룹에 배치 expression을 다시이 선을 배치해야 카테고리?

: 별도로 정수와 연산자를 처리 할 필요가없는 경우 그냥 split 전 운영자 후 장소에 look-around 메커니즘

String expression = "23*12+11"; 
for (String s : expression.split("(?<=[-+*/()])|(?=[-+*/()])")) 
    System.out.println(s); 

출력을 사용 할 수 있습니다 나는

String expression = "23*12+11"; 
Pattern p = Pattern.compile("(\\d+)|([-+*/()]+)"); 
Matcher m = p.matcher(expression); 
while (m.find()){ 
    if (m.group(1)==null){//group 1 is null so match must come from group 2 
     System.out.println("opperator found: "+m.group(2)); 
    }else{ 
     System.out.println("integer found: "+m.group(1)); 
    } 
} 
또한

같은 의미

23 
* 
12 
+ 
11 
0

이 하나

을보십시오 : 당신은 당신이 작업에 대한 잘못된 도구를 사용하고 계수 % 연산자

String expression = "2/3*1%(2+11)"; 

    Pattern pt = Pattern.compile("[-+*/()%]"); 
    Matcher mt = pt.matcher(expression); 
    int lastStart = 0; 
    while (mt.find()) { 
     if (lastStart != mt.start()) { 
      System.out.println("number:" + expression.substring(lastStart, mt.start())); 
     } 
     lastStart = mt.start() + 1; 
     System.out.println("operator:" + mt.group()); 
    } 

    if (lastStart != expression.length()) { 
     System.out.println("number:" + expression.substring(lastStart)); 
    } 

출력

number:2 
operator:/ 
number:3 
operator:* 
number:1 
operator:% 
operator:(
number:2 
operator:+ 
number:11 
operator:)