2009-10-02 8 views
178

Gibt es irgendeine ready-Funktion, die camel case-Strings in durch einen Unterstrich getrennte Strings konvertiert?Konvertieren von Kamelfall in Unterstreichungsfall in Rubin

Ich möchte etwas wie folgt aus:

"CamelCaseString".to_underscore  

"camel_case_string" zurückzukehren.

...

+35

FYI: Klein und unterstrichene ist „offiziell“ genannt Schlange Fall – Andrew

+3

Es ist komisch, "offiziell" in Anführungszeichen zu sehen, und das ist der beste Weg, es zu beschreiben. –

Antwort

299

Rails' ActiveSupport zum String unterstreichen fügt mit dem folgenden:

class String 
    def underscore 
    self.gsub(/::/, '/'). 
    gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). 
    gsub(/([a-z\d])([A-Z])/,'\1_\2'). 
    tr("-", "_"). 
    downcase 
    end 
end 

Dann können Sie Spaß Dinge tun:

"CamelCase".underscore 
=> "camel_case" 
+5

Wenn Sie 'tr (" - "," _ ")' in 'tr (" - "," _ ")' (dem ersten Parameter hinzugefügtes Leerzeichen) ändern, werden auch Leerzeichen in Unterstriche umgewandelt. Außerdem glaube ich nicht, dass du selbst "selbst" einbeziehen musst, oder zumindest funktioniert es für mich unter Ruby 1.9.3. –

+3

'require 'active_support/core_ext/string'' – konsolebox

16

Hier ist, wie Rails does it:

def underscore(camel_cased_word) 
    camel_cased_word.to_s.gsub(/::/, '/'). 
     gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). 
     gsub(/([a-z\d])([A-Z])/,'\1_\2'). 
     tr("-", "_"). 
     downcase 
    end 
+0

Es ist besser, den Operanden als Methodenargument zu haben, anstatt in die Core-String-Klasse einzudringen. – Pistos

+1

Stimmen Sie nicht zu - besser, wenn es in der Klasse funktioniert, wie es sein sollte, sonst müssen Sie es in ein Modul stecken und daran denken, es wo immer Sie es brauchen, einzuschließen. – Ghoti

+1

Auch diese Methode ist sowieso ein Teil von Rails 3 :) – Ghoti

45

One-Liner Ruby-Implementierung:

class String 
    # ruby mutation methods have the expectation to return self if a mutation occurred, nil otherwise. (see http://www.ruby-doc.org/core-1.9.3/String.html#method-i-gsub-21) 
    def to_underscore! 
    gsub!(/(.)([A-Z])/,'\1_\2') 
    downcase! 
    end 

    def to_underscore 
    dup.tap { |s| s.to_underscore! } 
    end 
end 

So "SomeCamelCase".to_underscore # =>"some_camel_case"

+2

Wie sind die anderen Lösungen nicht pures Rubin? – jrhicks

+0

Oh, sh ... Danke - Ich war mehr am Schreiben als am Lesen interessiert. Als Ergebnis haben Links auf Rails mich dazu gebracht, diese anderen Snippets für Rails-spezifisch zu halten. Geändert Antwort ... – kirushik

+1

gibt es einen anderen Fehler in meiner Bearbeitung, und es scheint nicht, dass ich es beheben kann. Hier ist der korrigierte Code: https://gist.github.com/4027440 –

61

können Sie verwenden

"CamelCasedName".tableize.singularize 

Oder nur

"CamelCasedName".underscore 

Beide Optionen Möglichkeiten werden "camel_cased_name" ergeben. Sie können weitere Details überprüfen here.

+8

Dies ist ein Teil der Implementierung von ActiveSupport :: Inflector, ohne sie können Sie diese String-Erweiterungen nicht verwenden (versuchen Sie in der reinen IRB-Konsole: "ThisCamelCaseString" .underscore, dann 'active_support/inflector' anfordern und erneut versuchen) –

+5

Downvoted weil das kein einfacher Rubin ist. – Papipo

25

Es gibt eine Rails eingebaute Methode ‚Unterstrich‘ genannt, die Sie für diesen Zweck verwenden können

"CamelCaseString".underscore #=> "camel_case_string" 

Die ‚Unterstrich‘ Verfahren typischerweise als Inverse von ‚camelize‘ betrachtet werden können

+0

undefined Methode 'Unterstrich 'für" ... ": String – Dorian

+2

Es ist eine ActiveSupport-Methode – Dorian

6

Check out snakecase von Ruby Facets

folgende Fälle behandelt werden, wie unten zu sehen:

"SnakeCase".snakecase   #=> "snake_case" 
"Snake-Case".snakecase  #=> "snake_case" 
"Snake Case".snakecase  #=> "snake_case" 
"Snake - Case".snakecase #=> "snake_case" 

Von: https://github.com/rubyworks/facets/blob/master/lib/core/facets/string/snakecase.rb

class String 

    # Underscore a string such that camelcase, dashes and spaces are 
    # replaced by underscores. This is the reverse of {#camelcase}, 
    # albeit not an exact inverse. 
    # 
    # "SnakeCase".snakecase   #=> "snake_case" 
    # "Snake-Case".snakecase  #=> "snake_case" 
    # "Snake Case".snakecase  #=> "snake_case" 
    # "Snake - Case".snakecase #=> "snake_case" 
    # 
    # Note, this method no longer converts `::` to `/`, in that case 
    # use the {#pathize} method instead. 

    def snakecase 
    #gsub(/::/, '/'). 
    gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). 
    gsub(/([a-z\d])([A-Z])/,'\1_\2'). 
    tr('-', '_'). 
    gsub(/\s/, '_'). 
    gsub(/__+/, '_'). 
    downcase 
    end 

    # 
    alias_method :underscore, :snakecase 

    # TODO: Add *separators to #snakecase, like camelcase. 

end 
1

Ich würde dies mag:

class String 

    # \n returns the capture group of "n" index 
    def snikize 
    self.gsub(/::/, '/') 
    .gsub(/([a-z\d])([A-Z])/, "\1_\2") 
    .downcase 
    end 

    # or 

    def snikize 
    self.gsub(/::/, '/') 
    .gsub(/([a-z\d])([A-Z])/) do 
     "#{$1}_#{$2}" 
    end 
    .downcase 
    end 

end 

Affe Patch von String Klasse. Es gibt Klassen, die mit zwei oder mehr Großbuchstaben beginnen.

3

Short oneliner für CamelCases wenn Sie Leerzeichen enthalten auch (nicht richtig funktionieren, wenn Sie ein Wort dazwischen mit kleinen Start Buchstaben haben):

a = "Test String" 
a.gsub(' ', '').underscore 

    => "test_string"