2014-01-23 40 views
1

我是初學者Regex。我以爲我會在沒有幫助的情況下完成此任務,但不能。正則表達式在Ruby中找到'a'或'an'的句子

我想從下面的句子找到article word對(其中文章必須爲A或):

This is a sentence. An egg is a word. A gee another word. 
Last line is a word. Ocean is very big. 

我用這個正則表達式:

/[(An)|(an)|a|A]\s+\w+[\s|.]/ 

捕獲對是:

'a sentence.', 'n egg ', 'a word.', 'A gee ', 'a word.', 'n is '. 

圖案以上coul完全沒有捕獲An egg。然而,更奇怪的是它抓住'n is 'Ocean is

什麼可能是正確的模式來提取它?

+0

您需要包括圍繞這些比賽串字邊界。請參閱正則表達式文檔中的'\ b'。例如,'/\b[(An)|(an)|a|A]\b\s+\w+[\s|.]/ – lurker

+1

'''n egg'和'n is'是你的原因正在混合[character classes('[...]']](http://ruby-doc.org/core-2.1.0/Regexp.html#class-Regexp-label-Character+Classes)和[alternation ('|')](http://ruby-doc.org/core-2.1.0/Regexp.html#class-Regexp-label-Alternation)。它們在某些方面是相似的,但是一個字符類只會匹配一個字符 - 您的正則表達式的[(An)|(an)| a | A]'部分基本上與[Aan]或' (A | A | n)的'。 – matt

回答

1
s = 'This is a sentence. An egg is a word. A gee another word.\nLast line is a word. Ocean is very big.' 
s.scan /(?<=\A|\s)[Aa]n?\s+[A-Za-z]+/m 
# => [ 
# [0] "a sentence", 
# [1] "An egg", 
# [2] "a word", 
# [3] "A gee", 
# [4] "a word" 
# ] 

這裏,我們去:/(?<=\A|\s)[Aa]n?\s+[A-Za-z]+/m

首先是回顧後不匹配「的是」在那我們找了(也許資本),後面可能跟着「N」,「大洋」。然後空格和單詞本身。最終m表示多行。

爲了避免使用回顧後,可以在正則表達式更改爲:

/\b[Aa]n?\s+[A-Za-z]+/m 

UPD應該避免使用\w在這裏,因爲\w比賽[A-Za-z0-9_]尤其要注意下劃線。

+0

後視速度慢嗎?這解決了我的目的/ \ b [Aa] n?\ s + \ w +/m。你選擇[A-Za-z] +的任何理由? – ram

+0

這裏沒關係。 – mudasobwa

+0

如果我的單詞包含下劃線,該怎麼辦? – ram

1

嘗試簡化爲\b(An|an|a|A) \w+\b

2

添加單詞邊界:

/\b(an?)\s+\w+/i 

編輯:n切不可資本)

/\b([aA]n?)\s+\w+/ 
+0

「a」可能是資本,而不是「n」。 – mudasobwa

+0

這也可以匹配「aN」或「AN」,但如果沒有關係,它是最優雅/簡單的解決方案。 – tenub

+0

@mudasobwa'我'螞蟻結束使它不區分大小寫。 –

0

我會用一個非常簡單的模式,與scan一起找到所有發生次數:

sentence = <<EOT 
This is a sentence. An egg is a word. A gee another word. 
Last line is a word. Ocean is very big. 
EOT 

sentence.scan(/\b an? \s+ [a-z]+/imx) 
# => ["a sentence", "An egg", "a word", "A gee", "a word"] 

我正在使用t他x標誌提高了模式的可讀性。

模式分解爲:

  • \b:字 - 邊界所以只有"a""an"匹配。 (不區分大小寫。)
  • an?:匹配"a""an"
  • \s+:匹配一個或多個空格。
  • [a-z]+:僅匹配字母的連續運行。這很重要,因爲使用\w字符類的任何模式也將匹配0..9和「_」(下劃線)。您的示例不包含這些內容,但包含這些字符的任何文本都可能會給您帶來不好的結果。
  • i標誌表示忽略大小寫。 m標誌表示將文本視爲單行文本。通常線端更重要。 x表示圖案中的空格不重要,因此需要\s來標記它們應該在的位置。

如果你想尾隨標點符號或空格,加.到模式的結尾:

sentence.scan(/\b an? \s+ [a-z]+ ./imx) 
# => ["a sentence.", "An egg ", "a word.", "A gee ", "a word."]