2010-09-12 72 views
0

我在網上找到了這個代碼片段,目的是提交任意數字,包括帶小數的數字...... 99999999 => 99,999,999。我可以看到它使用正則表達式,但我對「1.reverse $,$ 2」糊塗說明Ruby Commify大整數方法

def commify(n) 
    n.to_s =~ /([^\.]*)(\..*)?/ 
    int, dec = $1.reverse, $2 ? $2 : "" 
    while int.gsub!(/(,|\.|^)(\d{3})(\d)/, '\1\2,\3') 
    end 
    int.reverse + dec 
end 

誰能解釋什麼是這個代碼怎麼回事?

回答

5

$1$2$3 ...是Perl遺留的。它們是capture group變量,即它們捕獲正則表達式中的組。

一個命名組由圓括號表示。因此,第一個捕獲組匹配([^\.]),它是任何非點號字符,並且(\..*)匹配點字符\.以及其後任何其他字符。

請注意,第二組是可選的,因此在下面的行中您有三元表達式$2 ? $2 : "",這是一種用於獲取空白字符串捕獲值的密碼方式。

int, dec = $1, $2_or_blank_stringparallel assignment。 Ruby支持一次分配多個變量,它與int = $1.reversed然後dec = $2沒什麼不同,所以int現在保存整數部分(反轉)和dec數字的小數部分。我們現在對第一個感興趣。

下一個空的while會進行字符串替換。方法gsub!替換了seconf參數中值的正則表達式的所有出現。但如果沒有發生變化,則返回nil,結束while

/(,|\.|^)(\d{3})(\d)/表達式匹配:

  1. (,|\.|^)逗號,點或字符串的開頭
  2. (\d{3})三位數字
  3. (\d)第四數字

然後將其替換爲。字符串替換中的\n表示第n個捕獲組,就像變量$n一樣。所以,它基本上是:如果我有四位數字,只需在第三位之後加一個逗號即可。重複,直到找不到四位數的組

然後,只需再次顛倒整數部分並追加小數部分即可。

5

n.to_s =~ /([^\.]*)(\..*)?/所取的數量作爲一個字符串,並存儲一切小數點前(或者乾脆一切,如果沒有小數點)在$1和一切後,包括它在$2

int, dec = $1.reverse, $2 ? $2 : ""商店$1int$2,或如果""$2反向是nil,在dec。換句話說,int現在包含小數點前的部分反轉,並且dec包含該點之後的部分(未反轉)。

下一行將每三位逗號插入int。所以通過再次逆轉int,我們從最後每三個地方插入逗號插入的數字的原始組成部分。現在我們再添加dec,並在正確的位置用逗號獲得原始數字。

3

另一種方式:

class Integer 
    def commify 
    self.to_s.gsub(/(\d)(?=(\d{3})+$)/,'\1,') 
    end 
end 

然後,你可以做12345678.commify,並得到字符串12,345,678

這裏還有一個處理浮點數:

class Float 
    def commify 
    self.to_s.reverse.gsub(/(\d\d\d)(?=\d)(?!\d*\.)/,'\1,').reverse 
    end 
end