Conversión de convenciones de codificación

22

En ese Golf de codificación, debe convertir una convención de codificación con TitleCase a lower_case_with_underscores. ¡Y viceversa!

Especificación

Cambie la carcasa de la siguiente manera:

  • Si el carácter de subrayado es un delimitador, cambie la carcasa a Título de caso sin ninguno de los delimitadores.
  • Si hay varias palabras sin delimitador, cambie la carcasa a minúsculas y agregue un carácter de subrayado como delimitador.
  • En el caso de una sola palabra (o un carácter): cambie la carcasa a Título de caso si la palabra comienza con minúscula; cambie la carcasa a minúscula si la palabra comienza con mayúscula.

Caracteres permitidos:

  • De la A a la Z
  • de la A a la Z
  • subrayado ( _).

La entrada con palabras mixtas en mayúsculas no está permitida. Ejemplos de casos no permitidos:

  • Coding_Convention_Conversion
  • a_BC

Casos de ejemplo

Input                        | Expected Output
===========================================================
CodingConventionConversion   | coding_convention_conversion
coding_convention_conversion | CodingConventionConversion
abc                          | Abc
Abc                          | abc
ABC                          | a_b_c
a_b_c                        | ABC
a                            | A
A                            | a

Reglas

  • Está permitido usar ToUpper, ToLowery ToTitleCasefunciones.
  • Se permite el uso de expresiones regulares.
  • : ¡el código más corto en bytes gana!
Dariusz Woźniak
fuente
¿Está bien usar una ToTitleCasefunción? No especificaste, así que supongo que está bien.
Justin
@Justin: Buena pregunta de hecho. Hagámoslo más divertido y no permitamos la función ToTitleCase :)
Dariusz Woźniak
Maldición ... mi solución se basa en eso
Justin
1
@Justin: Bien, no lo especifiqué al principio, así que en ese caso, permitámoslo de todos modos.
Dariusz Woźniak

Respuestas:

4

Pyth, 25 bytes 29 33 35 40

Guardado 2 bytes gracias a @Dennis

Guardado 4 bytes gracias a @FryAmTheEggman

?rIz0smrd4cz\_tsXzrG1*\_G

Pruébalo en línea

Downgoat
fuente
Su enlace necesita ser actualizado.
isaacg
Cuando trato de poner "abc" como entrada, produce "bc" como salida. ¿Error? :)
Dariusz Woźniak
Para arreglar lo que @ DariuszWoźniak notó, puede cambiar su condición de /z\_a rIz0. También creo que encontré una alternativa de la misma longitud para agregar el programa de guiones bajos: tsXzrG1_Mcj\_G2quizás alguien pueda jugar más golf ...
FryAmTheEggman
Ah, lo encontré:tsXzrG1*\_G
FryAmTheEggman
8

Jolf, 35 bytes

Ahorra 1 byte gracias a @ Cᴏɴᴏʀ O'Bʀɪᴇɴ . Esto está codificado en ISO 8859-7.

? hI'_ΜGI'_dpyH0pxRGIL0"(?=[A-Z])'_

Woohoo mi primer programa Jolf!

Explicación

   // I = input
? hI'_                              // If input contains _
       GI'_                          // Split on _
      Μ    d                         // Loop, then join
            pyH0                     // Make the first character uppercase
                                    // ELSE...
                  RGIL0"(?=[A-Z])    // Split *after* all uppercase chars
                                 '_  // join with _ 
                px                   //Make lowercase

Pruébalo en línea

Downgoat
fuente
Puede usar la separación de cadenas al final, por lo que se convierte en "(?=[A-Z])'_. La cadena se cierra automáticamente.
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ oh, genial, gracias!
Downgoat
7

Retina , 37

¡Gracias a @ MartinBüttner por guardar 4 bytes!

^|[A-Z]
_$0
T`Ll`lL`_.
^_|_(?=[A-Z])

(Tenga en cuenta la nueva línea final).

Pruébalo en línea. Tenga en cuenta que esto incluye un extra m`para configurar un par de líneas para tratar cada línea de entrada por separado, de modo que todos los casos de prueba se puedan ejecutar de una vez. Este no es un requisito de la pregunta, por lo que no se cuentan en el puntaje.

  • Las líneas 1 y 2 se insertan _al principio de la entrada o antes de las letras mayúsculas. Todas las palabras ahora están _separadas, sin importar el caso.
  • La línea 3 cambia el caso de la primera letra de cada palabra.
  • Las líneas 4 y 5 se eliminan _al comienzo de la entrada o cuando van seguidas de una letra mayúscula.
Trauma digital
fuente
Esto ahorra cuatro bytes: retina.tryitonline.net/…
Martin Ender
También puede evitar la línea vacía final omitiendo la última ?=y reemplazando esa etapa con $1(aunque no afecta el recuento de bytes).
Martin Ender
@ Martin Muy bien, ¡gracias!
Trauma digital
5

GNU Sed, 46

¡Gracias a @TobySpeight por guardar 2 bytes!

La puntuación incluye +1 para -E(o -r) la opción de sed.

s/(^|_)([a-z])/\u\2/g
t
s/[A-Z]/_\l&/g
s/^_//

Pruébalo en línea.

Sed bastante sencillo:

  • La línea 1 sustituye el comienzo de la línea o _, seguido de una letra minúscula con la mayúscula de esa letra. La gmarca para srealizar esta sustitución para cada instancia encontrada
  • tsalta a la :etiqueta sin nombre si hubo coincidencias para la sustitución anterior. Esta etiqueta está implícitamente al final.
  • De lo contrario, todas las letras mayúsculas se sustituyen por _las minúsculas de esa letra
  • Esto deja un guión _antes de la primera letra. s/^_//elimina eso.
Trauma digital
fuente
1
@Toby Gracias. -Efunciona en mi GNU sed 4.2.2 (Ubuntu 14.04.3), aunque no está en la página de manual. Leí en alguna parte [cita requerida] que -Ees la nueva opción de Posix que se agregará oficialmente a GNU Sed en una versión más reciente, pero que ya está allí de manera no oficial. De todos modos, -rhace lo correcto si -Eno funciona para usted.
Trauma digital
@Toby líneas 280-282 de SED / sed.c son /* Undocumented, for compatibility with BSD sed. */ case 'E': case 'r':.
Trauma digital
@Digital: me equivoqué; mi sed no aceptar -Ecomo sinónimo de -r. No estaba pasando correctamente un programa mínimo, por ejemplosed -E -e Q
Toby Speight
4

JavaScript (ES6), 87 bytes

s=>s.replace(/[A-Z]|(^|_)(.)/g,(c,_,l,i)=>l?l.toUpperCase():(i?"_":"")+c.toLowerCase())

Explicación

Dependiendo de qué parte de la expresión regular coincida, reemplaza la coincidencia con el caso opuesto.

s.replace(
  /[A-Z]|(^|_)(.)/g,
  (c,_,l,i)=>
    l?
      (i?"_":"")+c.toLowerCase()
    :l.toUpperCase()
)

Prueba

var solution = s=>s.replace(/[A-Z]|(^|_)(.)/g,(c,_,l,i)=>l?l.toUpperCase():(i?"_":"")+c.toLowerCase())
<input type="text" id="input" value="coding_convention_conversion" />
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>

usuario81655
fuente
2

Ruby, 101 87 75 bytes

->s{s.gsub(/^.|[A-Z]/,'_\0').gsub(/_./,&:swapcase).gsub(/_(?=[A-Z])|^_/,'')}

Desafortunadamente, esto hace exactamente lo mismo que la solución Retina, ya que ese método terminó siendo más corto que cualquier otra cosa que se me ocurrió.

Justin
fuente
2

Python 3, 130 bytes

Intento rápido y sucio con expresiones regulares para dividir las tapas. Fuerza bruta: si alguien puede llegar a un enfoque diferente, estoy seguro de que esto puede ser vencido.

import re
lambda s:('_'.join(re.findall('[A-Z][a-z]*',s)).lower(),''.join([a[0].upper()+a[1:]for a in s.split('_')]))[s.islower()]
Ogaday
fuente
2

PHP 160 bytes

No es el más corto, pero para completar aquí mi solución en PHP, $ s contiene la cadena para convertir:

trim(preg_replace_callback('/((^[a-z]|_[a-z])|([A-Z]))/',function($m){return empty($m[2])?'_'.strtolower($m[3]):strtoupper(str_replace('_','',$m[2]));},$s),'_')
Camello
fuente
1
Bienvenido a Programming Puzzles y Code Golf Stack Exchange. Bien hecho por publicar algo en un idioma que sabías que no iba a ganar. los desafíos del código de golf se realizan principalmente dentro de los idiomas, por lo que usar un lenguaje que no sea de golf es bueno. +1 d: -D
wizzwizz4
1

Perl 6 ,  73 72 71   68 bytes

{.comb(/<:Lu><:Ll>*|<:Ll>+/).map({/<:Lu>/??.lc!!.tc}).join('_'x?/<:Lu>/)} # 73
{.comb(/<:Lu><:Ll>*|<:L>+/).map({/<:Lu>/??.lc!!.tc}).join('_'x?/<:Lu>/)}  # 72
{/<:Lu>/??S:g/(^)?(<:Lu>)/{$0||'_'}$1.lc()/!!S:g/[^|_](<:Ll>)/$0.tc()/}   # 71
{.comb(/<:Lu><:Ll>*|<:L>+/).map({/<:Lu>/??.lc!!.tc}).join('_'x!/_/)}      # 68

Uso:

# give it a lexical name
my &code = {...}

for <CodingConventionConversion coding_convention_conversion abc Abc ABC a_b_c a A>
{ say .&code }
coding_convention_conversion
CodingConventionConversion
Abc
abc
a_b_c
ABC
A
a

Explicación:

{
  .comb( / <:Lu><:Ll>* | <:L>+ / ) # grab the "words" only
  .map({
      /<:Lu>/ # if the word has uppercase
    ??
      .lc     # lowercase the whole word
    !!
      .tc     # otherwise titlecase the word
   })
  .join(  # join the words
    '_'   # with '_'
    x     # repeated
    !/_/  # zero times if it had a _, otherwise once
  )
}

Puede que se pregunte por qué usé las propiedades Unicode ( <:Lu>, <:Ll>) en lugar de solo una clase de caracteres. En Perl 6 ya no se deletrean [a-z], se deletrean, <[a..z]>que es 1.6 veces más grande. Los corchetes [ … ]se usan para agrupar sin capturar, que se deletreaba como (?: … )en Perl 5.

Brad Gilbert b2gills
fuente
1

Japt, 40 bytes

UfV="%A" ?UrV@'_s!Y +Xv} :Ur"^.|_."_sJ u

¡Pruébelo en línea!

Cómo funciona

           // Implicit: U = input string
UfV="%A"   // Set variable V to the string "\\A", and get all matches in U.
?          // If the list is not null:
UrV@     } //  Replace each match X and its index Y with this function:
'_s!Y +Xv  //   Return "_".slice(!Y) (1 for Y=0, 0 for anything else) + X.toLowerCase().
:          // Otherwise:
Ur"^.|_."  //  Replace the char at the beginning and each char following an underscore with:
_sJ u      //   The last char of the match (the letter) .toUpperCase().
ETHproducciones
fuente
1

Perl 5, 42 bytes

40 bytes más 2 para -p(gracias, dev-null )

s/[A-Z]/_\l$&/g||s/(^|_)(.)/\u$2/g;s/_//
msh210
fuente
En Windows, usando perl y MINGW32, no obtengo salida, ¿qué me estoy perdiendo?
ChatterOne
@ChatterOne No sé qué es MINGW32, pero funcionó bien para mí en Strawberry Perl. Usar en -Elugar de -e.
msh210
1

𝔼𝕊𝕄𝕚𝕟 3, 15 caracteres / 32 bytes (no competitivo)

⟮ѨDZï⟯≠ï?Ⅰ:ѨȎѨƎï

Try it here (Firefox only).

v3 se lanzó después de este desafío, con un montón de correcciones de errores y actualizaciones de la biblioteca.

Explicación

Esto es solo un mashup de builtins.

⟮ѨDZï⟯≠ï?Ⅰ:ѨȎѨƎï // implicit: ï=input
⟮ѨDZï⟯≠ï?        // check if ï is NOT in snake_case
       Ⅰ       // if so, then convert to snake_case
        :ѨȎѨƎï // otherwise, convert to camelCase and make the first letter UPPERCASE
Mama Fun Roll
fuente
1

Python 3 , 86 bytes

lambda s,u='_':''.join([u[i>u:]+i.lower()for i in(s<u)*s]or[u]+s.title().split(u))[1:]

Pruébalo en línea!

También funciona en Python 2 .

Aprovechando el hecho conveniente de que el valor ascii para _(95) está justo entre los de las letras mayúsculas (65-90) y minúsculas (97-122), lo que permite una fácil comparación de cadenas.

Jitse
fuente
1

Adelante (gforth) , 129 bytes

: f bounds dup c@ 32 xor emit 1+ ?do i c@ '_ < if ." _"i c@ 32 + emit then i c@ '_ > if i 1- c@ '_ = 32 * i c@ + emit then loop ;

Pruébalo en línea!

Explicación del código

: f              \ start a new word definition
  bounds         \ convert string address and length to beginning and ending address
  dup c@         \ get the first character
  32 xor emit    \ convert to the opposite case and output
  1+             \ add 1 to beginning of string (skip starting char)
  ?do            \ begin counted loop over string character addresses
    i c@ '_ <    \ check if char is uppercase 
    if           \ if it is:
      ." _"      \ output underscore
      i c@       \ get current char
      32 + emit  \ convert to lowercase and output
    then         \ end if block
    i c@ '_ >    \ check if lowercase (not '_')
    if           \ if it is:
      i 1- c@    \ get the previous character
      '_ = 32 *  \ if it's an underscore, multiply by 32 (true = -1 in forth)
      i c@ +     \ add result to current char (make uppercase if previous was '_')
      emit       \ output resulting char
    then         \ end if block
  loop           \ end loop
;                \ end word definition
reffu
fuente