2012-01-16 28 views
4

我試圖用正則表達式得到所有的單詞,但只有[a-zA-Z]。 因此,對於「我是男孩」,我希望{「我」,「我」,「一」,「男孩」} ,但對於「我a1m ab * y」,我想{「我」,「a」}因爲「a1m」和「b * y」包含[a-zA-Z]以外的字符。用正則表達式從一個句子找到單詞[a-zA-Z]

所以,我得到的話,我想檢查

  1. ,如果它是在字符串的開頭,然後如果有字
  2. 否則以後空間有一個空間,我只檢查前,在單詞
  3. 之後,如果它是最後一個單詞,那麼檢查單詞前是否有空格。

所以我結束了在Java中是這樣的:

Pattern p = Pattern.compile("^[a-zA-Z]+ |^[a-zA-Z]+$| [a-zA-Z]+$| [a-zA-Z]+"); 
Matcher m = p.matcher("i am good"); 
while(m.find()) System.out.println(m.group()); 

不過,我只得到 「」 和 「」。 因爲當我得到「我」時,「我」之後有一個空格。 所以剩下的字符串是「很好」「 由於」am「不在字符串的開頭,它也沒有返回。

你們可以提供任何意見嗎? 有沒有辦法只偷看下一個角色,而不是返回空間?

+0

這是什麼正則表達式引擎? – 2012-01-16 04:27:27

+0

我必須是正則表達式的noob,因爲我甚至不能回答這個問題。我使用的是6.0 java,對於正則表達式庫,我使用的是java.util.regex。*。希望能回答這個問題。 – 2012-01-16 12:46:05

+0

這是一個合理的答案。不幸的是,我對Java正則表達式一無所知,所以我不知道它是否支持lookahead/lookbehind斷言(這是我在下面的答案中使用的)。你只需要測試以找出答案。 – 2012-01-16 20:42:39

回答

6

假設你的正則表達式引擎支持前瞻/向後斷言,您可以使用類似以下內容:

(^|(?<=)[a-zA-Z]+($|(?=)) 

這裏的每個部件做什麼的簡短描述:

(^|(?<=)):這是說「如果一句話從這裏開始,我們感興趣」。具體而言,
    ^:匹配行的開頭,或
    (?<=):匹配,其由前面空間的任何點,而無需實際消耗空間本身。這被稱爲積極向後看斷言。

[a-zA-Z]+:這應該是顯而易見的,但它匹配任何連續的ASCII字母字符的運行。

($|(?=)):這說「如果這個詞在這裏完成,我們就完成了」。具體而言,
    $:匹配行的末尾,或
    (?=):匹配後跟一個空格的任何點,而無需實際消耗空間本身。這被稱爲積極的前瞻斷言。


請注意,這個特定的正則表達式不會將單詞作爲單詞計數,如果它跟隨標點符號。這實際上可能不是你想要的,但你描述了檢查空間,所以這正是正則表達式所做的。如果你想支持之後是簡單的標點符號的話,你可能會修改,去年原子是

($|(?=[ .,!?])) 

,如果它的後面有一個空格,句號,逗號,感嘆號或問號將匹配的單詞。如果你願意,你也可以更加細緻。

+0

字界? '\ B [A-ZA-Z] + \ B'? – 2012-01-16 05:17:03

+0

@ mathematical.coffee:單詞邊界不符合「a1m」部分不匹配的要求。字面界限,「我a1m ab * y」會匹配「我」,「a」,「m」,「a」,「b」,「y」 – 2012-01-16 05:31:56

+0

aha謝謝,我知道我錯過了一些東西,它不會與'a1m'匹配,因爲alpha-> ​​numeric不是邊界,但會錯誤地匹配'b'和'y')。乾杯! – 2012-01-16 05:43:19

0

這只是一個說明,如果你不想使用像凱文巴拉德建議的東西。您可以將字符串分解爲令牌,然後您可以檢查每個令牌以確保它僅包含[a-zA-Z]。

要打破它爲標記,做這樣的事情:

String message="The text of the message to be scanned."; 
StringTokenizer st=new StringTokenizer(message); 
while (st.hasMoreTokens()) 
    { 
     checkWord(st.nextToken()); 
     idx++; 
    } 

然後您可以編寫一個函數來檢查,如果該令牌是由[A-ZA-Z]的。由於沒有空白處理,我認爲你會發現處理這些令牌要容易得多,而不是整個字符串。

祝你好運。

+0

謝謝!我實際上也是這樣編碼的,但我只是想知道是否可以純粹用正則表達式來完成。 – 2012-01-16 15:29:46

2

您可以使用簡單的模式,例如\b[A-Za-z]+\b嗎? (該\ b元字符分隔非單詞字符(例如,空格和標點字字符(例如,字母)。))

代碼

Pattern p = Pattern.compile("\\b[A-Za-z]+\\b"); 
Matcher m = p.matcher("i am good"); 
while(m.find()) System.out.println(m.group()); 

主要生產{ 「我」, 「上午」,「好「}。

編輯 當mathematical.coffee發表評論時,上述失敗。表達式

(?<=^|\s)[A-Za-z]+(?=\W*(?:\s*$|\s)) 

可能會更好。對於字符串I a1m a b*y boy am is!! or,匹配產生「我」,「a」,「男孩」,「上午」,「是」,「或」。

如果在前面的表達「是!!」應該被忽略,可以使用表達式(?<=^|\s)[A-Za-z]+(?=$|\s)代替。在前面的例子中,它不返回「is」,而是返回其他單詞(I,a,boy,am或者)。

+0

我以爲相同,但在'b * y'上失敗(它不應該匹配它,而是單獨匹配'b'和'y')。 – 2012-01-16 05:43:38

相關問題