2012-05-26 46 views
4

我正在使用帶分隔符的掃描器,並且遇到了一個我想要了解的奇怪行爲。瞭解scanner中的useDelimiter:爲什麼我會得到空白的令牌?

我使用這個PROGRAMM:

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); 
    } 

輸出是:

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}+)+". 
相關問題