CamelCase2snake_case ()


13

Écrire une fonction pour convertir le texte CamelCased en snake_case: FunctionForHTMLManipulationdevientfunction_for_html_manipulation

Le texte saisi sera un identifiant unique approprié dans de nombreuses langues. Il doit commencer par une lettre anglaise, puis être suivi d'un nombre quelconque de lettres ou de chiffres anglais. Aucun autre caractère (espaces, symboles, etc.) n'est autorisé.

Chaque "mot" dans le texte CamelCased commencera par une majuscule, sauf au début du texte ou immédiatement après un chiffre, et sera suivi de zéro ou plusieurs lettres, toutes dans le même cas. Les groupes de chiffres seront considérés comme des mots séparés mais passeront inchangés.

En d'autres termes, une lettre minuscule suivie d'une lettre majuscule indique une rupture de mot. N'importe quelle lettre et chiffre l'un à côté de l'autre indique une rupture de mot. Une lettre majuscule suivie d'une autre lettre majuscule et d'une lettre minuscule indique une rupture de mot.

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

Les deux Buy24Beerset buy24beersdevenir buy_24_beers.
MacDonaldAndObriandevient mac_donald_and_obrian.
MACDonaldAndOBriandevient mac_donald_and_o_brian.


6
" MACDonaldAndOBriandevient mac_donald_and_o_brian" - pourquoi?
Qwertiy

2
@Qwertiy Parce que je pensais que ces noms seraient amusants. Sauf si vous posez des questions sur la règle, qui est couverte par ...UUl...=> ...u_ul....
CJ Dennis


@DigitalTrauma Étonnamment proche de ma question d'origine mais sans se plaindre d'être deux questions en une et pas de downvotes! La plus grande différence réside dans le traitement des cordes ALLCAPS. J'ai cherché pour voir si la question avait été posée auparavant mais je ne l'ai pas trouvée.
CJ Dennis

1
@ggorlen le ...indique qu'il est au milieu d'une chaîne.
CJ Dennis

Réponses:


7

Rétine , 61 37 octets

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

Essayez-le en ligne! (Légèrement modifié pour exécuter une suite de tests complète.)

Explication

Au lieu de trouver des limites de mots pour insérer des traits de soulignement, nous faisons simplement correspondre chaque mot et ajoutons a _. Faire correspondre les mots de gauche est un peu ennuyeux à cause de la UUlrègle, mais en utilisant la correspondance de droite à gauche de .NET, nous pouvons facilement faire correspondre les mots avec avidité. Pour éviter un début _, nous utilisons les limites de la rétine.

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

Le ractive le mode de droite à gauche, le 1>dit à Retina de tout traiter sauf la première correspondance (en comptant de gauche à droite). Ensuite , il y a quatre types de « mots »: Ulll, lll, UUU, ddd. Ceux-ci sont facilement adaptés au motif donné. La substitution écrit juste un _suivi du mot lui-même.

T`L`l

Cela transforme simplement les majuscules en minuscules pour terminer la transformation.


6

JavaScript (ES6), 79 octets

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

3

JavaScript (ES6), 89 octets

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

2

Powershell, 77 octets

Basé sur la réponse de Neil .

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

Script de test moins 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"
}

Production:

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 octets

Brièvement supprimé, +24 octets pour avoir utilisé le mauvais RegEx.

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

Essayez-le en ligne!

Fondamentalement, les mêmes que les solutions JavaScript.


Cela ne fonctionne pas avec buy24beerset MACDonaldAndOBrian. Pardon.
mazzy

1
@mazzy corrigé, merci.
Gabriel Mills

0

Facteur, 140 octets

[ 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 ]

Non golfé:

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

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

Essayez-le en ligne!

Cette solution bénéficie de la notation abrégée de Lua pour les classes de caractères de C (minuscule %l, majuscule %u, alphabétique %a, chiffre %d), de la notation frontière ( %f[]) et de la correspondance entière ajoutée en tant que première capture implicite en l'absence de toute autre capture.


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.