Si j'ai une chaîne qui ressemble à ceci:
"this_is_the_string"
Dans un script bash, je voudrais le convertir en PascalCase, c'est-à-dire UpperCamelCase pour ressembler à ceci:
"ThisIsTheString"
J'ai trouvé que la conversion vers lowerCamelCase peut se faire comme ceci:
"this_is_the_string" | sed -r 's/([a-z]+)_([a-z])([a-z]+)/\1\U\2\L\3/'
Malheureusement, je ne connais pas assez les expressions rationnelles pour modifier cela.
shell-script
user1135541
la source
la source
\U\2
insère le texte trouvé du deuxième groupe, converti en TOUTES MAJUSCULES. Comparer à\u\2
, qui insère le texte en cas de phrase, avec uniquement le premier caractère en majuscule. (2) Tous les exemples ci-dessous traduiront «this_is_a_string» en «ThisIsAString» - c'est ce que vous avez demandé, mais il est légèrement difficile à lire. Vous voudrez peut-être réviser vos exigences pour le cas spécial d'un mot à une lettre (sous-chaîne). … (Suite)(^|_)
à(\<|_)
.Réponses:
Remplacez le motif
(^|_)
au début de la chaîne ou après un trait de soulignement - premier groupe([a-z])
, lettre minuscule unique - deuxième groupeen
\U\2
mettant le deuxième groupe en majusculeg
.la source
\U
est une extension GNU de POSIX.sed -r 's/(^|[-_ ]+)([0-9a-z])/\U\2/g'
. Les chaînes comme "this_is_2nd_string" fonctionnent également.Puisque vous utilisez
bash
, si vous avez stocké votre chaîne dans une variable, vous pouvez également le faire uniquement en shell:${uscore//_/ }
remplace tout_
par un espace,(....)
divise la chaîne en un tableau,${arr[@]^}
convertit la première lettre de chaque élément en majuscule, puisprintf %s ..
imprime tous les éléments les uns après les autres.Vous pouvez stocker la chaîne en chameau dans une autre variable:
et l'utiliser / réutiliser plus tard, par exemple:
Ou, avec
zsh
:(${(s:_:)uscore})
divise la chaîne_
en un tableau, met en(C)
majuscule la première lettre de chaque élément etprintf %s ...
imprime tous les éléments les uns après les autres.Pour la stocker dans une autre variable, vous pouvez utiliser
(j::)
pour joindre les éléments:et l'utiliser / réutiliser plus tard:
la source
Voici un moyen Perl:
Il peut traiter des chaînes de longueur arbitraire:
Il correspondra à tout caractère (
.
) qui vient après le début de la chaîne ou un trait de soulignement ((^|_)
) et le remplacera par la version majuscule de lui-même (uc($&)
). La$&
est une variable spéciale qui contient tout ce qui vient d'être mis en correspondance. Lee
à la fin des///ge
permet l'utilisation d'expressions (lauc()
fonction dans ce cas) dans la substitution et leg
fait remplacer toutes les occurrences de la ligne. La deuxième substitution supprime les traits de soulignement.la source
perl -pe 's/(^|_)([a-z])/uc($2)/ge'
Il n'est pas nécessaire de représenter la chaîne entière dans une correspondance d'expression régulière - sed a le
/g
modificateur qui vous permet de parcourir plusieurs correspondances et de remplacer chacune d'elles:Le premier regex est
_\([a-z]\)
- chaque lettre après le trait de soulignement; la seconde correspond à la première lettre d'une chaîne.la source
Je ne mets cette réponse que parce qu'elle est plus courte et plus simple que toute autre jusqu'à présent.
Il dit: upcase, le caractère suivant un
_
ou le début. Les lettres non ne seront pas modifiées, car elles n'ont pas de casse.la source
FooBar
mais le trait de soulignement devrait être supprimé conformément aux instructions. Si je comprends bien les instructions._
) soient plutôt indiqués par des transitions de casse. Étant donné que «FOO_BAR» → «FOOBAR» est clairement faux (car il supprime les informations de rupture de mot), bien que «FOO_BAR» → «FooBar» puisse être correct. (4) De même, une cartographie provoquant des collisions semble contraire à l'esprit de la question. Par exemple, je pense qu'une réponse qui convertit «DO_SPORTS» et «DOS_PORTS» en la même cible est fausse.En perl:
C'est également compatible i18n:
la source
Je l'ai fait de cette façon:
et a obtenu ce résultat:
la source