CamelCase2snake_case ()

13

Tulis fungsi untuk mengonversi teks CamelCased ke snake_case: FunctionForHTMLManipulationmenjadifunction_for_html_manipulation

Teks input akan menjadi pengidentifikasi tunggal yang cocok dalam banyak bahasa. Itu harus dimulai dengan huruf bahasa Inggris, kemudian diikuti oleh sejumlah huruf atau angka bahasa Inggris. Tidak ada karakter lain (spasi, simbol, dll.) Yang diperbolehkan.

Setiap "kata" dalam teks CamelCased akan dimulai dengan huruf kapital kecuali di awal teks atau segera setelah digit, dan diikuti oleh nol atau lebih huruf, semua huruf yang sama. Kelompok digit akan dianggap sebagai kata-kata yang terpisah tetapi melewati tidak berubah.

Dengan kata lain, huruf kecil diikuti dengan huruf besar menunjukkan kata istirahat. Setiap huruf dan angka di sebelah satu sama lain menunjukkan kata istirahat. Huruf besar diikuti oleh huruf besar lain dan huruf kecil menunjukkan kata istirahat.

...lU...=> ...l_u...
...l9...=> ...l_9...
...U9...=> ...u_9...
...9l...=> ...9_l...
...9U...=> ...9_u...
...UUl...=>...u_ul...

Keduanya Buy24Beersdan buy24beersmenjadi buy_24_beers.
MacDonaldAndObrianmenjadi mac_donald_and_obrian.
MACDonaldAndOBrianmenjadi mac_donald_and_o_brian.

CJ Dennis
sumber
6
" MACDonaldAndOBrianmenjadi mac_donald_and_o_brian" - mengapa?
Qwertiy
2
@ Qwertiy Karena saya pikir nama-nama itu akan menyenangkan. Kecuali Anda bertanya tentang aturan, yang dicakup oleh ...UUl...=> ...u_ul....
CJ Dennis
Sangat terkait erat
Digital Trauma
@DigitalTrauma Luar biasa dekat dengan pertanyaan asli saya tetapi tanpa keluhan tentang menjadi dua pertanyaan dalam satu dan tidak ada downvotes! Perbedaan terbesar adalah pada perawatan string ALLCAPS. Saya mencari tahu apakah pertanyaannya sudah diajukan sebelumnya tetapi saya tidak menemukannya.
CJ Dennis
1
@ggorlen yang ...menunjukkan itu di tengah-tengah sebuah string.
CJ Dennis

Jawaban:

7

Retina , 61 37 byte

r1>`[A-Z]?[a-z]+|[A-Z]+|\d+
_$&
T`L`l

Cobalah online! (Sedikit dimodifikasi untuk menjalankan suite uji lengkap.)

Penjelasan

Alih-alih menemukan batas kata untuk disisipkan garis bawah, kami cukup mencocokkan setiap kata dan menambahkan a _. Mencocokkan kata-kata dari kiri agak mengganggu karena UUlaturan, tetapi menggunakan pencocokan kanan-ke-kiri .NET kita dapat dengan mudah mencocokkan kata-kata dengan rakus. Untuk menghindari petunjuk _, kami menggunakan batasan Retina.

r1>`[A-Z]?[a-z]+|[A-Z]+|\d+
_$&

The rmengaktifkan modus kanan-ke-kiri, 1>mengatakan Retina untuk proses semuanya kecuali pertandingan pertama (penghitungan dari kiri ke kanan). Lalu ada empat jenis "kata": Ulll, lll, UUU, ddd. Ini mudah dicocokkan dengan pola yang diberikan. Substitusi hanya menulis _diikuti oleh kata itu sendiri.

T`L`l

Ini hanya mengubah huruf besar menjadi huruf kecil untuk menyelesaikan transformasi.

Martin Ender
sumber
6

JavaScript (ES6), 79 byte

s=>s.match(/[A-Z]+(?=[A-Z][a-z]|\d|$)|[A-Z]?[a-z]+|\d+/g).join`_`.toLowerCase()
pengguna81655
sumber
3

JavaScript (ES6), 89 byte

s=>s.replace(/\d(?=\D)|\D(?=\d)|[a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z])/g,"$&_").toL‌​owerCase()
Neil
sumber
2

Powershell, 77 byte

Berdasarkan jawaban Neil .

$args-creplace'\d(?=\D)|\D(?=\d)|[a-z](?=[A-Z])|.(?=[A-Z][a-z])','$&_'|% *wer

Skrip uji yang kurang golf:

$f = {

$args-creplace'\d(?=\D)|\D(?=\d)|[a-z](?=[A-Z])|.(?=[A-Z][a-z])','$&_'|% toLower

}

@(
    ,("Buy24Beers", "buy_24_beers")
    ,("buy24beers", "buy_24_beers")
    ,("MacDonaldAndObrian", "mac_donald_and_obrian")
    ,("MACDonaldAndOBrian", "mac_donald_and_o_brian")
    ,("BigD", "big_d")
) | % {
    $s,$expected = $_
    $result = &$f $s
    "$($result-ceq$expected): $result"
}

Keluaran:

True: buy_24_beers
True: buy_24_beers
True: mac_donald_and_obrian
True: mac_donald_and_o_brian
True: big_d
mazzy
sumber
1

PowerShell, 68 92 byte

Secara singkat dihapus, +24 byte karena menggunakan RegEx yang salah.

($args-creplace'\d(?=\D)|\D(?=\d)|[a-z](?=[A-Z])|.(?=[A-Z][a-z])','$&_').Trim('_').ToLower()

Cobalah online!

Pada dasarnya sama dengan solusi JavaScript.

Gabriel Mills
sumber
Itu tidak bekerja dengan buy24beersdan MACDonaldAndOBrian. Maaf.
mazzy
1
@ Mazzy diperbaiki, terima kasih.
Gabriel Mills
0

Faktor, 140 byte

[ R/ [a-z][A-Z][a-z]/ [ dup from>> swap dup to>> swap seq>> subseq R/ [A-Z][a-z]/ [ "_" prepend ] re-replace-with ] re-replace-with >lower ]

Tidak Disatukan:

: slice>subseq ( slice -- subseq )
dup from>> swap dup to>> swap seq>> subseq ;

: camel-case>snake-case ( string -- string' )
    R/ [a-z][A-Z][a-z]/ [
        slice>subseq R/ [A-Z][a-z]/
        [ "_" prepend ] re-replace-with
    ] re-replace-with >lower ;
kucing
sumber
0

Lua , 135 byte

function snake(s)return s:gsub('%f[^%l]%u','_%1'):gsub('%f[^%a]%d','_%1'):gsub('%f[^%d]%a','_%1'):gsub('(%u)(%u%l)','%1_%2'):lower()end

Cobalah online!

Solusi ini mendapat manfaat dari notasi steno Lua untuk kelas karakter C (huruf kecil %l, huruf besar %u, alfabet %a, digit %d), notasi perbatasan ( %f[]), dan dari keseluruhan pertandingan ditambahkan sebagai tangkapan pertama implisit tanpa adanya tangkapan lainnya.

pengendara sepeda
sumber
0

Python 2 , 82 byte

lambda x:re.sub('(\d+|.([A-Z]*|[a-z]*)(?![a-z]))(?!$)','\\1_',x).lower()
import re

Cobalah online!

Erik the Outgolfer
sumber