Konversi Konvensi Pengkodean

22

Dalam Coding Golf itu, Anda harus mengonversi satu konvensi pengkodean dengan TitleCase ke lower_case_with_underscores. Dan sebaliknya!

Spesifikasi

Ganti casing dengan cara berikut:

  • Jika karakter garis bawah adalah pembatas, ubah casing menjadi Title Case tanpa pembatas.
  • Jika ada beberapa kata tanpa pembatas, ubah casing menjadi huruf kecil dan tambahkan karakter garis bawah sebagai pembatas.
  • Dalam hal hanya satu kata (atau satu karakter): ganti casing ke Title Case jika kata tersebut dimulai dengan huruf kecil; ganti casing ke huruf kecil jika kata dimulai dengan huruf besar.

Karakter yang diizinkan:

  • A hingga Z
  • a hingga z
  • garis bawah ( _).

Masukan dengan kata-kata cased campuran tidak diizinkan. Contoh kasus yang dilarang:

  • Coding_Convention_Conversion
  • a_BC

Contoh Kasus

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

Aturan

  • Itu diizinkan untuk digunakan ToUpper, ToLowerdan ToTitleCasefungsi.
  • Menggunakan ekspresi reguler diperbolehkan.
  • : kode terpendek dalam byte menang!
Dariusz Woźniak
sumber
Apakah menggunakan ToTitleCasefungsi oke? Anda tidak menentukan, jadi saya anggap tidak apa-apa.
Justin
@ Justin: Pertanyaan yang bagus. Mari kita membuatnya lebih menyenangkan dan melarang fungsi ToTitleCase :)
Dariusz Woźniak
Sial ... solusi saya bergantung padanya
Justin
1
@ Justin: Oke - Saya tidak menentukannya di awal, jadi dalam hal ini - mari kita biarkan saja.
Dariusz Woźniak

Jawaban:

4

Pyth, 25 byte 29 33 35 40

Disimpan 2 byte berkat @Dennis

Disimpan 4 byte berkat @FryAmTheEggman

?rIz0smrd4cz\_tsXzrG1*\_G

Cobalah online

Downgoat
sumber
Tautan Anda perlu diperbarui.
isaacg
Ketika saya mencoba menempatkan "abc" sebagai input, ia menghasilkan "bc" sebagai output. Bug? :)
Dariusz Woźniak
Untuk memperbaiki apa yang diperhatikan oleh DariuszWoźniak, Anda dapat mengubah kondisi Anda dari /z\_menjadi rIz0. Saya juga percaya saya menemukan alternatif yang sama panjangnya dengan menambahkan program garis bawah tsXzrG1_Mcj\_G2
:,
Ah, menemukannya:tsXzrG1*\_G
FryAmTheEggman
8

Jolf, 35 byte

Menghemat 1 byte berkat @ Cᴏɴᴏʀ O'Bʀɪᴇɴ . Ini dikodekan dalam ISO 8859-7.

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

Woohoo program Jolf pertamaku!

Penjelasan

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

Cobalah online

Downgoat
sumber
Anda dapat menggunakan pemisahan string di bagian akhir, sehingga menjadi "(?=[A-Z])'_. Tali ditutup secara otomatis.
Conor O'Brien
@ C coolO'Bʀɪᴇɴ oh, keren, terima kasih!
Downgoat
7

Retina , 37

Terima kasih kepada @ MartinBüttner karena telah menghemat 4 byte!

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

(Perhatikan baris tambahan.)

Cobalah online. Catatan ini termasuk tambahan m`untuk mengonfigurasi beberapa baris untuk memperlakukan setiap jalur input secara terpisah sehingga semua testcases dapat dijalankan dalam sekali jalan. Ini bukan persyaratan pertanyaan, jadi ini tidak dihitung dalam skor.

  • Baris 1 dan 2 masukkan _di awal input atau sebelum huruf besar. Semua kata sekarang _dipisahkan, terlepas dari kasusnya.
  • Baris 3 bertukar kasus huruf pertama dalam setiap kata.
  • Baris 4 dan 5 hapus _pada saat awal input, atau ketika diikuti oleh huruf besar.
Trauma Digital
sumber
Ini menghemat empat byte: retina.tryitonline.net/...
Martin Ender
Anda juga dapat menghindari trailing baris kosong dengan menghilangkan yang terakhir ?=dan mengganti tahap itu dengan $1(tidak mempengaruhi jumlah byte).
Martin Ender
@ Martin Sangat bagus - terima kasih!
Trauma Digital
5

GNU Sed, 46

Terima kasih kepada @TobySpeight untuk menghemat 2 byte!

Skor mencakup +1 untuk opsi -E(atau -r) untuk sed.

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

Cobalah online.

Sed sederhananya:

  • Baris 1 menggantikan awal baris atau _, diikuti dengan huruf kecil dengan huruf besar huruf itu. The gbendera untuk sMelakukan substitusi ini untuk setiap contoh ditemukan
  • tmelompat ke :label yang tidak disebutkan namanya jika ada kecocokan untuk substitusi di atas. Label ini secara implisit di akhir.
  • Kalau tidak, semua huruf besar diganti dengan _huruf kecil dari huruf itu
  • Ini meninggalkan _petunjuk di depan huruf pertama. s/^_//menghapus itu.
Trauma Digital
sumber
1
@Toby Terima kasih. -Ebekerja di GNU sed 4.2.2 saya (Ubuntu 14.04.3), meskipun tidak ada di halaman manual. Saya membaca di suatu tempat [rujukan?] -EYaitu opsi Posix yang lebih baru yang secara resmi akan ditambahkan ke GNU Sed dalam rilis yang lebih baru, tetapi sudah ada di sana secara tidak resmi. Apapun, -rlakukan hal yang benar jika -Etidak berhasil untuk Anda.
Digital Trauma
@Toby baris 280-282 sed / sed.c are /* Undocumented, for compatibility with BSD sed. */ case 'E': case 'r':.
Trauma Digital
@Digital - Saya salah; saya sed tidak menerima -Esebagai sinonim untuk -r. Saya tidak benar melewati program minimal misalnyased -E -e Q
Toby Speight
4

JavaScript (ES6), 87 byte

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

Penjelasan

Tergantung pada bagian mana dari regex yang cocok, itu menggantikan pertandingan dengan kasus yang berlawanan.

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

Uji

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>

pengguna81655
sumber
2

Ruby, 101 87 75 byte

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

Sayangnya, ini melakukan hal yang persis sama dengan solusi Retina, karena metode itu ternyata lebih pendek dari apa pun yang saya dapatkan.

Justin
sumber
2

Python 3, 130 byte

Upaya cepat dan kotor menggunakan regex untuk membelah tutup. Kekuatan yang cukup kasar: jika ada yang bisa datang dengan pendekatan yang berbeda, saya yakin ini bisa dikalahkan.

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
sumber
2

PHP 160 byte

bukan yang terpendek tetapi untuk kelengkapan di sini solusi saya di PHP, $ s memiliki string untuk dikonversi:

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),'_')
Unta
sumber
1
Selamat datang di Programming Puzzles dan Code Golf Stack Exchange. Dilakukan dengan baik untuk memposting sesuatu dalam bahasa yang Anda tahu tidak akan menang. tantangan kode-golf sebagian besar dalam bahasa, jadi menggunakan bahasa non-golf itu bagus. +1 d: -D
wizzwizz4
1

Perl 6 ,  73 72 71   68 byte

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

Pemakaian:

# 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

Penjelasan:

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

Anda mungkin bertanya-tanya mengapa saya menggunakan properti Unicode ( <:Lu>, <:Ll>) alih-alih hanya kelas karakter. Dalam Perl 6 mereka tidak lagi dieja [a-z]mereka dieja <[a..z]>yang 1,6 kali lebih besar. Tanda kurung [ … ]digunakan untuk pengelompokan non-menangkap yang dieja seperti (?: … )dalam Perl 5.

Brad Gilbert b2gills
sumber
1

Japt, 40 byte

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

Uji secara online!

Bagaimana itu bekerja

           // 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().
Produksi ETH
sumber
1

Perl 5, 42 byte

40 byte plus 2 untuk -p(terima kasih, dev-null )

s/[A-Z]/_\l$&/g||s/(^|_)(.)/\u$2/g;s/_//
msh210
sumber
Di Windows, menggunakan perl dan MINGW32, saya tidak mendapatkan output, apa yang saya lewatkan?
ChatterOne
@ChatterOne Saya tidak tahu apa itu MINGW32, tapi itu bekerja dengan baik untuk saya di Strawberry Perl. Gunakan -Esebagai ganti -e.
msh210
1

𝔼𝕊𝕄𝕚𝕟 3, 15 karakter / 32 byte (tidak kompetitif)

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

Try it here (Firefox only).

v3 dirilis setelah tantangan ini, dengan banyak perbaikan bug dan pembaruan perpustakaan.

Penjelasan

Ini hanya mashup builtin.

⟮Ѩ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
sumber
1

Python 3 , 86 byte

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

Cobalah online!

Juga berfungsi di Python 2 .

Memanfaatkan fakta praktis bahwa nilai ascii untuk _(95) tepat di antara huruf besar (65-90) dan huruf kecil (97-122), yang memungkinkan perbandingan string yang mudah.

Jitse
sumber
1

Keempat (gforth) , 129 byte

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

Cobalah online!

Penjelasan Kode

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