2016-09-30 42 views
0

我有以下字符串:除了最後一個單詞外,我如何匹配字符串中的每個單詞?

Chicago CPA 
New York CPA 
West Virginia Accountant 

如何永遠只是砍掉在字符串中的最後一個字(和前面的空格),最後一個字之前保留所有換句話說?

上述數據集的那麼正確的版本是:

Chicago 
New York 
West Virginia 

此外,是否有可能以測試Rubular匹配組或者是有,我可以用它來測試正則表達式其他在線的正則表達式編輯器/測試儀與匹配的組?

編輯1

許多問題的答案都是理論的偉大。我讀了他們,我瞭解他們,我測試他們在香草串,他們似乎工作。但是當我在我的數據上嘗試它時,它不會。我被困了一段時間,我才意識到爲什麼。

這是我工作的HTML:

所以這個文本,我試圖做此字符串操作:

Chicago&nbsp;<strong>Cpa</strong> 

所以這是當我嘗試會發生什麼下面的每個答案。


@的Darshan的:

[56] pry(YPCrawler::PageCrawler)> @document.css('header h1.search-term').first.text 
=> "Chicago Cpa" 
[57] pry(YPCrawler::PageCrawler)> @document.css('header h1.search-term').first.text.class 
=> String 
[58] pry(YPCrawler::PageCrawler)> @document.css('header h1.search-term').first.text.match(/(.*) \w+\z/)[1] 
NoMethodError: undefined method `[]' for nil:NilClass 
from (pry):57:in `<class:PageCrawler>' 
[59] pry(YPCrawler::PageCrawler)> @document.css('header h1.search-term').first.text[/.*(?=\s\w+\z)/] 
=> nil 

@盧卡斯自己:

[60] pry(YPCrawler::PageCrawler)> @document.css('header h1.search-term').first.text 
=> "Chicago Cpa" 
[61] pry(YPCrawler::PageCrawler)> @document.css('header h1.search-term').first.text.class 
=> String 
[62] pry(YPCrawler::PageCrawler)> @document.css('header h1.search-term').first.text.split()[0...-1].join(' ') 
=> "" 

@埃裏克自己:

[65] pry(YPCrawler::PageCrawler)> @document.css('header h1.search-term').first.text 
=> "Chicago Cpa" 
[66] pry(YPCrawler::PageCrawler)> @document.css('header h1.search-term').first.text.class 
=> String 
[67] pry(YPCrawler::PageCrawler)> @document.css('header h1.search-term').first.text.split().reverse.drop(1).reverse.join(" ") 
=> "" 

@卡西米爾自己的(這個人是最好的,到目前爲止,實際上):

[68] pry(YPCrawler::PageCrawler)> @document.css('header h1.search-term').first.text 
=> "Chicago Cpa" 
[69] pry(YPCrawler::PageCrawler)> @document.css('header h1.search-term').first.text.class 
=> String 
[70] pry(YPCrawler::PageCrawler)> @document.css('header h1.search-term').first.text.sub(/\W+\w+\W*$/, '') 
=> "Chicago" 

@桑托斯自己:

[71] pry(YPCrawler::PageCrawler)> @document.css('header h1.search-term').first.text 
=> "Chicago Cpa" 
[72] pry(YPCrawler::PageCrawler)> @document.css('header h1.search-term').first.text.class 
=> String 
[73] pry(YPCrawler::PageCrawler)> @document.css('header h1.search-term').first.text[/(.*)\s/,1] 
=> nil 

我的道歉不這樣做這早些時候,但我沒有預料到這是一個問題。實現這一目標的

回答

4

,我會說我不使用正則表達式特別好,我不知道把我的頭頂部(也感覺不到傾向於基準或認真思考)這是否前言往往會比@ LucasP的非正則表達式更有效率。但是,這是我想到的對我來說,顯而易見的方法:

s.match(/(.*) \w+\z/)[1] 

這在串的一個或多個單詞字符前面加一個空格結束比賽,並把一切之前成團,你再搶。

data = ['Chicago CPA', 
     'New York CPA', 
     'West Virginia Accountant'] 

data.map{|s| s.match(/(.*) \w+\z/)[1]} 
# => ["Chicago", "New York", "West Virginia"] 

編輯:這種辦法,通過@CarySwoveland提出一個變體,是用前瞻表達無視我們要放棄的一部分,而不是我的推杆部分的初始方法,我們要爲捕獲我們然後訪問的組。這裏有一個版本的方法:

data.map{|s| s[/.*(?=\s\w+\z)/]} 
# => ["Chicago", "New York", "West Virginia"] 

編輯2:幫助將附加的信息,這是現在很清楚,你所面對的問題是,你有非打破空間,這甚至\s不匹配(\s只匹配ASCII空格,相當於[ \t\r\n\f])。因此,使用POSIX括號表達式[[:space:]]或明確地匹配\u00A0來表示不間斷空格字符的工作,假設所有都是非中斷空格。我更喜歡前者,因爲你可能有其他的空格有時會出現:

data.map{|s| s[/.*(?=[[:space:]]\w+\z)/]} 
+0

我看到了你要去的地方,但是這個正則表達式似乎並不匹配每個Rubular.com的「Chicago CPA」。它只匹配 – marcamillion

+2

@marcamillion再次,它適用於我的機器和rubular.com。我會將你的數據集轉儲到一個十六進制編輯器中,看看你的空白是怎麼回事。 –

+1

@marcamillion http://rubular.com/r/b9X60eAwNc –

2

的一種方法如下:

myString.split()[0...-1].join(' ') 

哪裏myString是要執行此操作的每個字符串。

  1. 首先你從字符串拆分到包含每個單詞的列表。

  2. 然後選擇包含除最後一個元素以外的所有元素的子列表。

  3. 最後你從列表返回到一個字符串。

+0

所以我最初嘗試了類似的東西,但當我嘗試分割這些字符串時,最奇怪的事情正在發生。 '>「Chicago Cpa」.split => [「Chicago Cpa」]'。它不會爲每個單詞創建一個新的元素......我覺得這很奇怪。什麼可能導致這個? – marcamillion

+1

@marcamillion當我複製並粘貼時,我會按照預期得到'[「Chicago」,「Cpa」]'。你有可能在你的字符串中有一些不可思議的空白嗎? –

+0

這是非常bizzarre。不知道爲什麼我的分裂不正確。我沒有看到任何不可思議的空白。 – marcamillion

0
"New York Accountant".split().reverse.drop(1).reverse.join(" ") 
+2

'split [0 ..- 2]'比split()更直接。reverse.drop(1).reverse'? –

+0

是的,但這是另一種選擇... – Eric

+0

我一直在努力弄清楚爲什麼你的建議不適用於我的實際數據,但是當我嘗試使用香草字符串時它的工作原理。我已經更新了有關我的數據實際外觀的更多詳細信息。 – marcamillion

1

假設你有一個以上的話,你可以使用一個替代:

'West Virginia Accountant'.sub(/\W+\w+\W*$/, '') 
+0

使用這種方法有什麼缺點?有什麼情況會導致誤報? – marcamillion

+0

@marcamillion:它取決於你稱之爲「一個單詞」,例如,這種模式會失敗,帶有重音字母的單詞(但這可以通過一些更改輕鬆解決),或者用名稱包含引號,例如「Scarlett O 'Hara'=>「Scarlett O」或帶有「出生在美國」的縮寫詞=>「出生在美國」,但您可以將模式更改爲「/ \ p {Z} + \ P {Z} + \ p {Z} * $ /'(其中'\ p {Z}'匹配所有unicode分隔符)。 –

0

嘗試以下。

str = ['Chicago CPA', 'New York CPA', 'West Virginia Accountant'] 

str.map{|s| s[0...s.rindex(' ')]} 

輸出:["Chicago", "New York", "West Virginia"]

使用正則表達式。

str2 = "West Virginia Accountant" 
p str2[/(.*)\s/,1] 

輸出:"West Virginia"

+0

我一直在努力弄清楚爲什麼你的建議不適用於我的實際數據,但是當我嘗試使用香草字符串時它的工作原理。我已經更新了有關我的數據實際外觀的更多詳細信息。 – marcamillion

+0

@marcamillion在你的實際字符串中包含' '。所以我的正則表達式無法檢測到這一點。所以你可以使用正則表達式'/ \ W + \ w + \ W * $ /'。你能超越你的實際的字符串嗎? –

0

您可以使用正則表達式/^(.*)\s+\w+\s*$/捕捉到一切,但最後一個字:

例子:

str = <<~EOF 
     Chicago CPA 
     New York CPA 
     West Virginia Accountant 
EOF 

str.each_line do |line| 
     puts line.match(/^(.*)\s+\w+\s*$/).captures.first 
end 

輸出:

Chicago 
New York 
West Virginia 
相關問題