Trabajar con la clase Ruby: capitalizar una cadena

Sep 23 2020

Estoy tratando de entender cómo trabajar con Clases en Ruby y realmente agradecería algunos conocimientos sobre esta área. Actualmente, tengo una tarea bastante simple para convertir una cadena con el comienzo de cada palabra en mayúscula. Por ejemplo:

Not Jaden-Cased: "How can mirrors be real if our eyes aren't real"
Jaden-Cased:     "How Can Mirrors Be Real If Our Eyes Aren't Real"

Este es mi código actualmente:

class String
  def toJadenCase
    split
    capitalize

  end
end

#=> usual case: split.map(&:capitalize).join(' ')


Producción:

Expected: "The Moment That Truth Is Organized It Becomes A Lie.",
 instead got: "The moment that truth is organized it becomes a lie."

Respuestas

1 CarySwoveland Sep 23 2020 at 01:30

Le sugiero que no contamine la Stringclase principal con la adición de un método de instancia. En su lugar, simplemente agregue un argumento al método para contener la cadena. Puede hacerlo de la siguiente manera, reduciendo la cadena y luego usándola gsubcon una expresión regular.

def to_jaden_case(str)
  str.downcase.gsub(/(?<=\A| )[a-z]/) { |c| c.upcase } 
end
to_jaden_case "The moMent      That trUth is organized, it becomes a lie."
  #=> "The Moment      That Truth Is Organized, It Becomes A Lie."

El motor de expresiones regulares de Ruby realiza las siguientes operaciones.

(?<=\A| )  : use a positive lookbehind to assert that the following match
             is immediately preceded by the start of the string or a space 
[a-z]      : match a lowercase letter

(?<=\A| )se puede reemplazar con la búsqueda hacia atrás negativa (?<![^ ]) , que afirma que la coincidencia no está precedida por un carácter que no sea un espacio.

Observe que al usar String # gsub con una expresión regular (a diferencia del baile split -process- join ), se conservan los espacios adicionales.

Cuando los espacios deben coincidir con una expresión regular, a menudo se ven los espacios en blanco ( \s) que coinciden. Aquí, por ejemplo, /(?<=\A|\s)[a-z]/funciona bien, pero a veces la coincidencia de espacios en blanco genera problemas, principalmente porque también coinciden con nuevas líneas ( \n) (así como con espacios, tabulaciones y algunos otros caracteres). Mi consejo es hacer coincidir los caracteres de espacio si los espacios deben coincidir. Si las pestañas también deben coincidir, use una clase de carácter ( [ \t]).

1 Ayudh Sep 22 2020 at 22:33

Intentar:

 def toJadenCase
    self.split.map(&:capitalize).join(' ')
 end