2012-05-30 90 views
1

任何人都可以向我解釋這個嗎?在紅寶石混淆中匹配正則表達式

str = "org-id:   N/A\n" 

puts str[/org-id:\s+(.+)\n/] 
=> "org-id:   N/A\n" 
str =~ /org-id:\s+(.+)\n/ 
puts $1 
=> "N/A" 

所有我需要的是

str =~ /org-id:\s+(.+)\n/ 
puts $1 
在一行

。 但str[/org-id:\s+(.+)\n/]str.slice(/org-id:\s+(.+)\n/)返回"org-id: N/A\n"和str.scan(/ org-id:\ s +(。+)\ n /)首先返回["N/A"](和數組)。爲什麼所有這些比賽的表現都不一樣?

回答

3

fine manual

STR [正則表達式]→new_str或零
STR [正則表達式,Fixnum對象]→new_str或零

如果Regexp被提供時,匹配部分str已退回。如果數字或名稱參數遵循正則表達式,則會返回MatchData的該組件。

所以,如果你這樣做str[/org-id:\s+(.+)\n/]那麼你得到整個匹配部分(AKA $&);如果你想第一個捕獲組(AKA $1),那麼你可以說:

puts str[/org-id:\s+(.+)\n/, 1] 
# 'N/A' 

如果你有在你的正則表達式的第二捕獲組,你想要什麼拍攝,你可以說str[regex, 2]等。你也可以使用一個名爲捕獲組正是如此一個符號:

puts str[/org-id:\s+(?<want>.+)\n/, :want] 

所以用正確的方式和參數,String#[]方便拉一個基於正則表達式,塊出一個字符串。

如果你看看手冊,你應該注意到String#[]String#splice是一樣的東西。


如果我們看一下String#=~,我們看到:

海峽=〜OBJ→Fixnum對象或零

匹配,如果OBJRegexp,用它作爲與str匹配的模式,並返回比賽開始的位置,或者如果不匹配則返回nil

所以,當你說:

str =~ /org-id:\s+(.+)\n/ 

$&得到'org-id: N/A',在$1'N/A',和運營商的返回值是數字0;如果在你的正則表達式中有另一個捕獲組,你會在$2中看到該部分。的=~的「nil或不nil」返回值可以讓你說這樣的話:

make_pancakes_for($1) if(str =~ /some pattern that makes (us) happy/) 

所以=~方便一氣呵成結合解析和布爾測試。


String#scan方法:

掃描(圖案)→陣列
掃描(圖案){|匹配,... |塊}→STR

兩種形式遍歷STR,匹配圖案(其可以是一個RegexpString)。對於每個匹配,都會生成結果並將其添加到結果數組或傳遞給塊。如果模式不包含組,則每個單獨的結果由匹配的字符串$&組成。如果模式包含組,每個單獨的結果本身就是一個數組,每個組包含一個條目。

所以scan給你匹配一個簡單的列表或匹配的AoA如果捕獲集團參與和scan是爲了拉開一個字符串轉換爲它的所有組成部件一氣呵成(有點像一個更復雜的版本的String#split)。

如果你想抓住所有從你的字符串(.+)比賽你會使用scanmap

array_of_ids = str.scan(/org-id:\s+(.+)\n/).map(&:first) 

但你只與麻煩,如果你知道會有幾個組織的IDS在str。掃描也將離開$&,$1,...設置爲scan中最後一場比賽的值;但如果您使用的是scan,那麼您將一次尋找幾個匹配項,以便這些全局變量不會非常有用。


三個正則表達式的方法([]=~scan)提供類似的功能,但他們填寫不同的利基。你可以用scan做到這一點,但這將是毫無意義的繁瑣,除非你是一個正交偏執者,然後你肯定不會在Ruby中工作,除非在極端的脅迫下,所以這並不重要。

0

這是一場比賽和一次比賽的區別。 Str [regex]返回匹配整個正則表達式的整個片段。 $ 1僅代表第一個()子句捕獲的匹配部分。