Konwersja konwencji kodowania

22

W tym golfie kodowania powinieneś przekonwertować jedną konwencję kodowania z TitleCase na lower_case_with_underscores. I wzajemnie!

Specyfikacja

Zmień obudowę w następujący sposób:

  • Jeśli znak podkreślenia jest ogranicznikiem, zmień obudowę na wielkość liter bez ogranicznika.
  • Jeśli jest wiele słów bez separatora, zmień wielkość liter na małe i dodaj znak podkreślenia jako separator.
  • W przypadku tylko jednego słowa (lub jednego znaku): zmień wielkość liter na Wielkość liter, jeśli słowo zaczyna się na małe litery; zmień obudowę na małe litery, jeśli słowo zaczyna się od wielkich liter.

Dozwolone postacie:

  • A do Z
  • a do Z
  • podkreślenie ( _).

Wpisywanie słów zawierających małe litery jest niedozwolone. Przykłady niedozwolonych przypadków:

  • Coding_Convention_Conversion
  • a_BC

Przykłady przypadków

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

Zasady

  • Dopuszcza się używać ToUpper, ToLowera ToTitleCasefunkcje.
  • Używanie wyrażeń regularnych jest dozwolone.
  • : wygrywa najkrótszy kod w bajtach!
Dariusz Woźniak
źródło
Czy używanie ToTitleCasefunkcji jest w porządku? Nie określiłeś, więc zakładam, że jest w porządku.
Justin
@Justin: Rzeczywiście dobre pytanie. Sprawmy, by było fajniej i nie zezwalajmy na funkcję ToTitleCase :)
Dariusz Woźniak
Cholera ... moje rozwiązanie na tym polega
Justin
1
@Justin: Dobra - nie określiłem tego na początku, więc w takim razie - i tak pozwólmy.
Dariusz Woźniak

Odpowiedzi:

4

Pyth, 25 bajtów 29 33 35 40

Zaoszczędzono 2 bajty dzięki @Dennis

Zaoszczędź 4 bajty dzięki @FryAmTheEggman

?rIz0smrd4cz\_tsXzrG1*\_G

Wypróbuj online

Downgoat
źródło
Twój link wymaga aktualizacji.
isaacg
Kiedy próbuję wstawić „abc” jako dane wejściowe, daje „bc” jako dane wyjściowe. Pluskwa? :)
Dariusz Woźniak
Aby naprawić to, co zauważył @ DariuszWoźniak, możesz zmienić swój stan z /z\_na rIz0. Wierzę również, że znalazłem alternatywną długość dodawania programu podkreślającego: tsXzrG1_Mcj\_G2może ktoś może
zagrać w
Ach, znalazłem to:tsXzrG1*\_G
FryAmTheEggman
8

Jolf, 35 bajtów

Oszczędza 1 bajt dzięki @ Cᴏɴᴏʀ O'Bʀɪᴇɴ . Jest to zakodowane w ISO 8859-7.

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

Woohoo mój pierwszy program Jolf!

Wyjaśnienie

   // 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

Wypróbuj online

Downgoat
źródło
Na końcu możesz użyć separacji ciągów, aby stała się "(?=[A-Z])'_. Ciąg zostanie automatycznie zamknięty.
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ och, spoko, dzięki!
Downgoat
7

Retina , 37

Dzięki @ MartinBüttner za oszczędność 4 bajtów!

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

(Zwróć uwagę na końcowy znak nowej linii).

Wypróbuj online. Uwaga: obejmuje to dodatkowe m`skonfigurowanie kilku linii do traktowania każdej linii wejściowej osobno, aby wszystkie przypadki testowe mogły być uruchomione za jednym razem. Nie jest to wymagane w pytaniu, więc nie są one uwzględniane w wyniku.

  • Wstawianie linii 1 i 2 _ albo na początku wprowadzania, albo przed dużymi literami. Wszystkie słowa są teraz _rozdzielane, niezależnie od wielkości liter.
  • Wiersz 3 zamienia wielkość liter pierwszej litery w każdym słowie.
  • Linie 4 i 5 usuwają _albo na początku wprowadzania, albo gdy następuje po nich duża litera.
Cyfrowa trauma
źródło
Oszczędza to cztery bajty: retina.tryitonline.net/…
Martin Ender
Możesz także uniknąć końcowej pustej linii, pomijając ostatni ?=i zastępując ten etap $1(nie wpływa to na liczbę bajtów).
Martin Ender
@Martin Bardzo dobrze - dzięki!
Cyfrowy uraz
5

GNU Sed, 46

Dzięki @TobySpeight za zapisanie 2 bajtów!

Wynik obejmuje +1 dla opcji -E(lub -r) do sed.

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

Wypróbuj online.

Dość prosty sed:

  • Wiersz 1 zastępuje początek wiersza lub _, a następnie małą literą, wielką literą tej litery. gFlagę srealizuje to podstawienie każdorazowo znaleziono
  • tprzeskakuje do :nienazwanej etykiety, jeśli były jakieś dopasowania dla powyższego podstawienia. Ta etykieta jest domyślnie na końcu.
  • W przeciwnym razie wszystkie wielkie litery zostaną zastąpione _małymi literami tej litery
  • Pozostawia to przewagę _przed pierwszą literą. s/^_//usuwa to.
Cyfrowa trauma
źródło
1
@Toby Thanks. -Edziała w moim GNU sed 4.2.2 (Ubuntu 14.04.3), chociaż nie ma go na stronie man. Czytałem gdzieś [potrzebne źródło], która -Ejest nowszą opcją Posix, która zostanie oficjalnie dodana do GNU Sed w nowszej wersji, ale jest już tam nieoficjalnie. Niezależnie od tego, -rczy działa dobrze, jeśli -Enie działa dla Ciebie.
Cyfrowy uraz
@Toby linie 280-282 z sed / sed.c/* Undocumented, for compatibility with BSD sed. */ case 'E': case 'r':.
Cyfrowy uraz
@Digital - pomyliłem się; My sed ma przyjąć -Ejako synonim -r. Nie przekazałem poprawnie minimalnego programu, np.sed -E -e Q
Toby Speight
4

JavaScript (ES6), 87 bajtów

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

Wyjaśnienie

W zależności od tego, która część wyrażenia regularnego jest dopasowana, zastępuje dopasowanie odwrotnym przypadkiem.

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

Test

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>

użytkownik 81655
źródło
2

Ruby, 101 87 75 bajtów

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

Niestety, robi to dokładnie to samo, co rozwiązanie Retina, ponieważ metoda ta okazała się krótsza niż cokolwiek innego, co wymyśliłem.

Justin
źródło
2

Python 3, 130 bajtów

Szybka i brudna próba użycia wyrażenia regularnego do podziału na czapki. Całkiem brutalna siła: jeśli ktoś może wymyślić inne podejście, jestem pewien, że można to pokonać.

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
źródło
2

PHP 160 bajtów

nie najkrótsze, ale dla kompletności tutaj moje rozwiązanie w PHP, $ s przechowuje ciąg do konwersji:

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),'_')
Wielbłąd
źródło
1
Witamy w Programowaniu łamigłówek i wymianie stosów kodów golfowych. Dobra robota, jeśli opublikujesz coś w języku, o którym wiedziałeś, że nie wygra. wyzwania związane z golfem są głównie w obrębie języków, więc dobrze jest używać języka nie golfowego. +1 d: -D
wizzwizz4 28.01.16
1

Perl 6 ,  73 72 71   68 bajtów

{.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

Stosowanie:

# 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

Wyjaśnienie:

{
  .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
  )
}

Być może zastanawiasz się, dlaczego użyłem właściwości Unicode ( <:Lu>, <:Ll>) zamiast tylko klasy znaków. W Perlu 6 nie są już pisane [a-z], są pisane, <[a..z]>co jest 1,6 razy większe. Nawiasy klamrowe [ … ]są używane do grupowania bez przechwytywania, które zostało przeliterowane jak (?: … )w Perl 5.

Brad Gilbert b2gills
źródło
1

Japt, 40 bajtów

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

Przetestuj online!

Jak to działa

           // 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().
ETHprodukcje
źródło
1

Perl 5, 42 bajtów

40 bajtów plus 2 za -p(dzięki, dev-null )

s/[A-Z]/_\l$&/g||s/(^|_)(.)/\u$2/g;s/_//
msh210
źródło
W systemie Windows, używając Perla i MINGW32, nie otrzymuję danych wyjściowych, czego mi brakuje?
ChatterOne
@ChatterOne Nie wiem, co to jest MINGW32, ale działało dla mnie dobrze na Strawberry Perl. Użyj -Ezamiast -e.
msh210
1

𝔼𝕊𝕄𝕚𝕟 3, 15 znaków / 32 bajty (niekonkurencyjne)

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

Try it here (Firefox only).

Wersja v3 została wydana po tym wyzwaniu, z kilkoma poprawkami błędów i aktualizacjami bibliotek.

Wyjaśnienie

To tylko połączenie wbudowanych plików.

⟮Ѩ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
źródło
1

Python 3 , 86 bajtów

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

Wypróbuj online!

Działa również w Python 2 .

Korzystając z wygodnego faktu, że wartość ascii dla _(95) znajduje się pomiędzy wielkimi i dużymi literami (65-90) i małymi literami (97-122), co pozwala na łatwe porównywanie ciągów.

Jitse
źródło
1

Dalej (gforth) , 129 bajtów

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

Wypróbuj online!

Objaśnienie kodu

: 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
źródło