Umwandlung des Kamelkastens in einen Unterstrich in Rubin

232

Gibt es eine Bereitschaftsfunktion, die Kamelfallstrings in durch Unterstriche getrennte Strings umwandelt?

Ich möchte so etwas:

"CamelCaseString".to_underscore      

um "camel_case_string" zurückzugeben.

...

Daniel Cukier
quelle
43
Zu Ihrer Information: Kleinbuchstaben und unterstrichen wird "offiziell" als Schlangenbuchstaben bezeichnet
Andrew
3
Es ist seltsam, "offiziell" in Anführungszeichen zu sehen, und doch ist das die beste Art, es zu beschreiben.
Stevenspiel
Aus irgendeinem Grund fehlt die Schlangenfallmethode. Schienen 4.
Abram

Antworten:

362

ActiveSupport von Rails fügt dem String den folgenden Unterstrich hinzu:

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 kannst du lustige Sachen machen:

"CamelCase".underscore
=> "camel_case"
jrhicks
quelle
5
Wenn Sie tr("-","_")zu tr("- ","_")(Leerzeichen zum ersten Parameter hinzugefügt) wechseln, werden Leerzeichen ebenfalls in Unterstriche umgewandelt. Ich glaube auch nicht, dass Sie es überhaupt aufnehmen müssen self., oder zumindest funktioniert es für mich unter Ruby 1.9.3.
Gus Shortz
6
require 'active_support/core_ext/string'
konsolebox
Die Unterstrichfunktion Active verwendet: github.com/rails/rails/blob/…
GreeKatrina
Unterstrich ist Methode von Rails nicht rubinrot, siehe apidock.com/rails/String/underscore .
S.Yadav
1
@ S.Yadav true Die Methode ist eine Rails, daher können Sie standardmäßig keinen Unterstrich aufrufen. Wenn Sie jedoch den verwendeten Code angeben und Rails als Quelle angeben, ist diese Antwort gut für Ruby. Sie können Rails einschließen oder nur Fügen Sie diese Funktion hinzu, die das Rails-Team geschrieben und getestet hat.
Michael Gorman
99

Sie können verwenden

"CamelCasedName".tableize.singularize

Oder nur

"CamelCasedName".underscore

Beide Optionen ergeben sich "camel_cased_name". Weitere Details können Sie hier überprüfen .

abo-elleef
quelle
11
Dies ist ein Teil der Implementierung von ActiveSupport :: Inflector. Ohne diese Implementierung können Sie diese String-Erweiterungen nicht verwenden (versuchen Sie es in der reinen irb-Konsole: "ThisCamelCaseString" .underscore, benötigen Sie dann 'active_support / inflector' und versuchen Sie es erneut)
Evgenia Manolova
3
Auf dem Etikett des OP steht "Ruby-on-Rails"
Julien Lamarche,
55

Einzeilige 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"

kirushik
quelle
2
Wie sind die anderen Lösungen nicht reiner Rubin?
Jrhicks
Oh, sh ... Danke - ich war mehr am Schreiben als am Lesen interessiert. Infolgedessen haben mich Links auf Rails dazu gebracht, diese anderen Snippets als Rails-spezifisch zu betrachten. Geänderte Antwort ...
Kirushik
1
Es gibt einen weiteren Fehler in meiner Bearbeitung, und es scheint nicht, dass ich ihn beheben kann. Hier ist der korrigierte Code: gist.github.com/4027440
Tim Harper
6
Vielleicht möchten Sie /([^A-Z])([A-Z]+)/stattdessen überlegen , um "ALLCAPS"-> "allcaps"statt"a_ll_ca_ps"
Nevir
4
Das ist eigentlich ein 10-Liner!
Kristianp
30

Es gibt eine in Rails integrierte Methode namens "Unterstrich", die Sie für diesen Zweck verwenden können

"CamelCaseString".underscore #=> "camel_case_string" 

Die "Unterstrich" -Methode kann typischerweise als Umkehrung von "Kamelisierung" betrachtet werden.

Aaditi Jain
quelle
1
undefinierte Methode "Unterstrich" für "...": String
Dorian
5
Es ist eine ActiveSupport-Methode
Dorian
20

So macht es Rails :

   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
Pesto
quelle
1
Es ist besser, den Operanden als Methodenargument zu verwenden, als in die String-Kernklasse einzudringen.
Pistos
1
Stimmen Sie nicht zu - es ist besser, wenn es in der Klasse so funktioniert, wie es sein sollte, oder Sie müssen es in ein Modul stecken und daran denken, es dort einzuschließen, wo Sie es benötigen.
Ghoti
1
Auch diese Methode ist sowieso Teil der Strings von Rails 3 :)
Ghoti
2
Wenn ich in diese Debatte einsteigen darf - Besser, wenn sie in die String-Klasse eindringt, wenn Sie sie einschließen =).
Evan Moran
7

Empfänger in Schlangenfall konvertiert: http://rubydoc.info/gems/extlib/0.9.15/String#snake_case-instance_method

Dies ist die Support-Bibliothek für DataMapper und Merb. ( http://rubygems.org/gems/extlib )

def snake_case
  return downcase if match(/\A[A-Z]+\z/)
  gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
  gsub(/([a-z])([A-Z])/, '\1_\2').
  downcase
end

"FooBar".snake_case           #=> "foo_bar"
"HeadlineCNNNews".snake_case  #=> "headline_cnn_news"
"CNN".snake_case              #=> "cnn"
Herr Schwarz
quelle
7

Schauen Sie sich den Schlangenkoffer von Ruby Facets an

Die folgenden Fälle werden wie folgt behandelt:

"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
Abram
quelle
Es funktioniert nicht mit einer Zeichenfolge mit Sonderzeichen. Beispiel:"Dumb Penguin's Egg".snakecase # => "dumb_penguin's_egg"
Khiav Reoy
6

Kurzer Oneliner für CamelCases, wenn auch Leerzeichen enthalten sind (funktioniert nicht richtig, wenn Sie ein Wort dazwischen mit einem kleinen Anfangsbuchstaben haben):

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

  => "test_string"
Andres Ehrenpreis
quelle
1
underscoreist nicht Teil von Ruby
dft
4

Falls jemand nach einem Fall sucht, in dem er Unterstriche auf Zeichenfolgen mit Leerzeichen anwenden und diese auch in Unterstriche konvertieren möchte, können Sie so etwas verwenden

'your String will be converted To underscore'.parameterize.underscore
#your_string_will_be_converted_to_underscore

Oder verwenden Sie einfach .parameterize ('_'), aber denken Sie daran, dass dieses veraltet ist

'your String will be converted To underscore'.parameterize('_')
#your_string_will_be_converted_to_underscore
Arman Petrosyan
quelle
1

Das würde mir gefallen:

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

Affenfeld der StringKlasse. Es gibt Klassen, die mit zwei oder mehr Buchstaben in Großbuchstaben beginnen.

rplaurindo
quelle
Sie müssen zu wechseln "\1_\2", '\1_\2'sonst erhalten Sie "came\u0001_\u0002ase"statt "camel_case"Ruby 2.5 ... vielleicht auch andere.
6ft Dan