2012-05-26 2 views
4

구분 기호가있는 스캐너를 사용 중이며 이상한 행동을 보았습니다. 이해하고 싶습니다.스캐너에서 useDelimiter 사용 : 왜 공백 토큰을 얻습니까?

Scanner sc = new Scanner("Aller à : Navigation, rechercher"); 
    sc.useDelimiter("\\s+|\\s*\\p{Punct}+\\s*"); 
    String word=""; 
    while(sc.hasNext()){ 
     word = sc.next(); 
     System.out.println(word); 
    } 

출력은 다음과 같습니다 :

나는이 programm에 사용하고 난 빈 토큰을 받고 있어요 왜 그렇게 처음에는 이해가 안

Aller 
à 

Navigation 
rechercher 

을의 documentation는 말한다 :

구분 기호 유형에 따라 빈 토큰이 반환 될 수 있습니다. 예를 들어, "\ s +"패턴은 구분 기호의 여러 인스턴스와 일치하므로 빈 토큰을 반환하지 않습니다. 구분 패턴 "\ s"는 한 번에 하나의 공백 만 전달하기 때문에 빈 토큰을 반환 할 수 있습니다.

\\s+ 나는 공백 토큰을 반환하는 이유는 무엇입니까?

그러면 정규식에 관해서 내가 알고 싶은 또 다른 것이 있습니다.

sc.useDelimiter("\\s*\\p{Punct}+\\s*|\\s+"); 

출력은 정확하고 내가 얻을 :

Aller 
à 
Navigation 
rechercher 

를이 방식으로 작동하는 이유는 정규식을 "반전"를 사용하여 구분 기호를 변경하는 경우?

편집 :이 케이스

:

Scanner sc = new Scanner("(23 ou 24 minutes pour les épisodes avec introduction) (approx.)1"); 
    sc.useDelimiter("\\s*\\p{Punct}+\\s*|\\s+"); //second regex 

난 아직도 introductionapprox 사이에 빈 토큰을 가지고있다. 그것을 피할 수 있습니까?

+1

공백이 있고 문장 부호가 뒤에 오는 곳에 두 개의 구분 기호 캡처가 발생한다고 생각합니다. 간단히''[\\ s \\ p {Punct}] +''를 사용하지 않을까요? 아니면 문제를 지나치게 간소화하고 있습니까? –

+0

@HovercraftFullOfEels 감사합니다 당신의 정규식은 내 요구에 완벽합니다! 나는'\\ s + | \\ p {Punct} +'(이 말로 시작했지만 언급하지 않았다)가 당신의 것과 똑같이하고 있다고 생각했지만 왜 그런 것이 아닌가? –

+0

그리고 여전히 \\ s * \\ p {Punct} + \\ s * | \\ s +'와'\\ s + | \\ s * \\ p {Punct}의 차이에 대한 설명을 찾고 있습니다. } + \ s *' –

답변

1

공백이있는 곳에 구두점이 오는 곳에서 두 개의 구분 기호 캡처가 발생하고 있다는 느낌이 들었습니다. 단순히 [\\s\\p{Punct}]+을 사용하지 않는 것이 어떻습니까?

이 정규식 \\s+|\\p{Punct}+은 먼저 빈 공간을 캡처하여 삼키고 다음 구분 기호를 구두점으로 사용합니다. 그것은 사이에 아무것도없이 서로 옆에있는 두 개의 분리 문자입니다 (빈 토큰).

+0

두 번째 패턴이 작동한다면 고맙습니다. \\ s * \\ p {Punct} + \\ s *'는 이미':'를 붙잡고 있기 때문에'\\ s + '이 사용되지 않고 공백이 없습니다. 내가 맞습니까? –

+0

@Alain : 나에게 맞는 소리. –

+0

도움에 감사드립니다. 나는 오늘 무언가를 배웠다! –

0

Scanner 클래스에서 빈 토큰 문제가 발생했습니다. 구분 기호 패턴은 괄호로 묶고 +을 그룹에 추가하여 욕심이 인 으로 만들어야한다고 생각합니다. 내가 사용한 패턴은 다음과 같습니다.

"((\\s)+|(\\\\r\\\\n)+|\\p{Punct}+)+". 
관련 문제