Conversione di una custodia color cammello in una sottolineatura in rubino


232

Esiste una funzione pronta che converte le stringhe della custodia del cammello in una stringa separata di sottolineatura?

Voglio qualcosa del genere:

"CamelCaseString".to_underscore      

per restituire "camel_case_string".

...


43
Cordiali saluti: minuscolo e sottolineato è "ufficialmente" chiamato caso serpente
Andrew

3
È strano vedere "ufficialmente" tra virgolette, eppure è il modo migliore per descriverlo.
Stevenspiel,

Per qualche motivo vedo che manca il metodo snakecase. Rotaie 4.
Abram,

Risposte:


363

ActiveSupport di Rails aggiunge il carattere di sottolineatura alla stringa usando quanto segue:

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

Quindi puoi fare cose divertenti:

"CamelCase".underscore
=> "camel_case"

5
Se cambi tr("-","_")in tr("- ","_")(spazio aggiunto al primo parametro), questo trasformerà anche gli spazi in caratteri di sottolineatura. Inoltre, non penso nemmeno che tu debba includerlo self., o almeno funziona per me sotto Ruby 1.9.3.
Gus Shortz,

6
require 'active_support/core_ext/string'
Konsolebox,

La funzione di sottolineatura che Active utilizza: github.com/rails/rails/blob/…
GreeKatrina

il carattere di sottolineatura è un metodo di Rails non ruby, consultare apidock.com/rails/String/underscore .
S.Yadav,

1
@ S.Yadav true il metodo è un Rails quindi non puoi chiamare il carattere di sottolineatura di default, ma fornendo il codice usato e citando le rotaie come fonte questa risposta è buona per ruby, dice che puoi includere rotaie, o semplicemente includere questa funzione che il team di Rails ha scritto e testato.
Michael Gorman,

99

Puoi usare

"CamelCasedName".tableize.singularize

O semplicemente

"CamelCasedName".underscore

Entrambe le opzioni verranno rese "camel_cased_name". Puoi controllare maggiori dettagli qui .


11
Questa è una parte dell'implementazione di ActiveSupport :: Inflector, senza di essa, non puoi usare quelle estensioni String (prova nella console irb pura: "ThisCamelCaseString" .underscore, quindi richiedi "active_support / inflector" e riprova)
Evgenia Manolova

3
L'etichetta del PO dice "ruby-on-rails"
Julien Lamarche,

55

Implementazione Ruby con una sola riga:

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

Così "SomeCamelCase".to_underscore # =>"some_camel_case"


2
come sono le altre soluzioni non rubino puro?
jrhicks,

Oh, sh ... Grazie - mi interessava di più scrivere che leggere. Di conseguenza, i collegamenti su Rails mi hanno fatto pensare che quegli altri frammenti fossero specifici di Rails. Risposta modificata ...
kirushik,

1
c'è un altro errore nella mia modifica e non sembra che io possa ripararlo. Ecco il codice corretto: gist.github.com/4027440
Tim Harper,

6
Puoi considerare /([^A-Z])([A-Z]+)/invece di gestire "ALLCAPS"-> "allcaps"anziché"a_ll_ca_ps"
Nevir il

4
Questo è in realtà un 10-liner!
kristianp,

30

Esiste un metodo integrato di Rails chiamato 'underscore' che puoi usare a questo scopo

"CamelCaseString".underscore #=> "camel_case_string" 

Il metodo "underscore" può essere generalmente considerato come inverso di "camelize"


1
metodo indefinito `underscore 'per" ... ": String
Dorian

5
È un metodo ActiveSupport
Dorian,

20

Ecco come 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

1
Meglio avere l'operando come argomento del metodo piuttosto che invadere la classe String di base.
Pistos,

1
Non essere d'accordo: è meglio che funzioni sulla classe come dovrebbe essere, altrimenti dovrai incollarlo in un modulo e ricordarti di includerlo ovunque ne avrai bisogno.
Ghoti,

1
Anche questo metodo fa comunque parte delle stringhe di Rails 3 :)
Ghoti

2
Se posso entrare in questo dibattito - Meglio che invada la classe di stringhe quando la includi =).
Evan Moran,


7

Dai un'occhiata a snakecase da Ruby Facets

Vengono gestiti i seguenti casi, come illustrato di seguito:

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

Da: 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

Non funziona con una stringa con carattere speciale. Esempio:"Dumb Penguin's Egg".snakecase # => "dumb_penguin's_egg"
khiav reoy,

6

Short oneliner per CamelCases anche con spazi inclusi (non funziona correttamente se hai una parola in mezzo con una piccola lettera iniziale):

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

  => "test_string"

1
underscorenon fa parte di ruby
dft

4

Nel caso in cui qualcuno cerchi un caso in cui deve applicare il carattere di sottolineatura alla stringa con spazi e desidera convertirli in caratteri di sottolineatura, puoi usare qualcosa di simile

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

O semplicemente usa .parameterize ('_') ma tieni presente che questo è deprecato

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

1

Mi piacerebbe questo:

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

Toppa di scimmia di Stringclasse. Ci sono classi che iniziano con due o più lettere maiuscole.


Devi cambiare "\1_\2"in '\1_\2'altrimenti finirai con "came\u0001_\u0002ase"invece "camel_case"di Ruby 2.5 ... forse anche altri.
6ft Dan
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.