CamelCase2snake_case ()


13

Scrivi una funzione per convertire il testo CamelCased in snake_case: FunctionForHTMLManipulationdiventafunction_for_html_manipulation

Il testo di input sarà un unico identificatore adatto in molte lingue. Deve iniziare con una lettera inglese, quindi essere seguito da un numero qualsiasi di lettere o cifre inglesi. Non sono ammessi altri caratteri (spazi, simboli, ecc.).

Ogni "parola" all'interno del testo CamelCased inizierà con una lettera maiuscola a meno che all'inizio del testo o immediatamente dopo una cifra, e sarà seguita da zero o più lettere, sempre nello stesso caso. I gruppi di cifre saranno considerati come parole separate ma passeranno invariati.

In altre parole, una lettera minuscola seguita da una lettera maiuscola indica un'interruzione di parola. Qualsiasi lettera e cifra l'una accanto all'altra indicano una pausa. Una lettera maiuscola seguita da un'altra lettera maiuscola e una lettera minuscola indica un'interruzione di parola.

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

Entrambi Buy24Beerse buy24beersdiventano buy_24_beers.
MacDonaldAndObriandiventa mac_donald_and_obrian.
MACDonaldAndOBriandiventa mac_donald_and_o_brian.


6
" MACDonaldAndOBriandiventa mac_donald_and_o_brian" - perché?
Qwertiy,

2
@Qwertiy Perché pensavo che quei nomi sarebbero stati divertenti. A meno che non ti stia chiedendo della regola, che è coperta da ...UUl...=> ...u_ul....
CJ Dennis,


@DigitalTrauma Incredibilmente vicino alla mia domanda originale, ma senza le lamentele sull'essere due domande in una e nessun voto negativo! La più grande differenza sta nel trattamento delle stringhe ALLCAPS. Ho cercato per vedere se la domanda era stata posta prima, ma non l'ho trovata.
CJ Dennis,

1
@ggorlen ...indica che è nel mezzo di una stringa.
CJ Dennis,

Risposte:


7

Retina , 61 37 byte

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

Provalo online! (Leggermente modificato per eseguire una suite di test completa.)

Spiegazione

Invece di trovare limiti di parole per inserire caratteri di sottolineatura, abbiniamo semplicemente ogni parola e anteponiamo a _. La corrispondenza delle parole da sinistra è un po 'fastidiosa a causa della UUlregola, ma usando la corrispondenza da destra a sinistra di .NET possiamo facilmente abbinare le parole avidamente. Per evitare un vantaggio _, facciamo uso dei limiti di Retina.

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

L' rattiva modalità da destra a sinistra, la 1>dice Retina di processo tutto tranne la prima partita (conteggio da sinistra a destra). Poi ci sono quattro tipi di "parole": Ulll, lll, UUU, ddd. Questi sono facilmente abbinati al modello dato. La sostituzione scrive solo una _seguita dalla parola stessa.

T`L`l

Questo trasforma semplicemente lettere maiuscole in minuscole per completare la trasformazione.


6

JavaScript (ES6), 79 byte

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

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()

2

Powershell, 77 byte

Basato sulla risposta di Neil .

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

Script di test meno golfato:

$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"
}

Produzione:

True: buy_24_beers
True: buy_24_beers
True: mac_donald_and_obrian
True: mac_donald_and_o_brian
True: big_d


1

PowerShell, 68 92 byte

Eliminato brevemente, +24 byte per l'utilizzo del RegEx errato.

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

Provalo online!

Fondamentalmente lo stesso delle soluzioni JavaScript.


Non funziona con buy24beerse MACDonaldAndOBrian. Scusa.
mazzy,

1
@mazzy risolto, grazie.
Gabriel Mills,

0

Fattore, 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 ]

Ungolfed:

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

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

Provalo online!

Questa soluzione beneficia della notazione abbreviata di Lua per le classi di caratteri di C (lettere minuscole %l, maiuscole %u, alfabetiche %a, cifre %d), notazione di frontiera ( %f[]) e dall'intera corrispondenza aggiunta come prima acquisizione implicita in assenza di altre acquisizioni.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.