アンダースコアをPascalCase、つまりUpperCamelCaseに変換します


28

次のような文字列がある場合:

"this_is_the_string"

bashスクリプト内で、PascalCase、つまりUpperCamelCaseに変換して、次のようにします。

"ThisIsTheString"

lowerCamelCaseへの変換は次のようにできることがわかりました。

"this_is_the_string" | sed -r 's/([a-z]+)_([a-z])([a-z]+)/\1\U\2\L\3/'

残念ながら、これを修正するための正規表現についてはあまり詳しくありません。


(1)この質問(およびこれまでに提示された回答)に関する限り、これは実際には重要ではありませんが、参考までに\U\2、見つかったテキストを2番目のグループから挿入し、すべて大文字に変換します。と比較して\u\2、最初の文字のみを大文字にして文章を挿入します。(2)以下に示すすべての例は、「this_is_a_string」を「ThisIsAString」に変換します。これはあなたが求めたものですが、少し読みにくいです。1文字の単語(部分文字列)の特殊なケースの要件を修正することもできます。…(続き)
スコット

(続き)…(3)1行に1つの文字列しかありませんか?そして、それは常に行の最初の(または唯一の)テキストですか?行の先頭にない文字列がある場合、以下の回答はそれをlowerCamelCaseに変換します。修正するには、Janisの答えを受け取ってに変更(^|_)(\<|_)ます。
スコット

回答:


44
$ echo "this_is_the_string" | sed -r 's/(^|_)([a-z])/\U\2/g'            
ThisIsTheString

代替パターン
(^|_)文字列の開始時またはアンダー後に-最初のグループ
([a-z])単一小文字-第二群
による
\U\2第2のグループを大文字化
g、グローバル。


4
注:\UはPOSIXのGNU拡張機能です。
Ciro Santilli新疆改造中心法轮功六四事件

1
ただメモ、あなたも数字をキャプチャする必要がありますsed -r 's/(^|[-_ ]+)([0-9a-z])/\U\2/g'。そのため、「this_is_2nd_string」などの文字列も機能します。
ピンキーン

9

を使用しているためbash、変数に文字列を保存した場合は、シェルのみでも実行できます。

uscore="this_is_the_string_to_be_converted"
arr=(${uscore//_/ })
printf %s "${arr[@]^}"
ThisIsTheStringToBeConverted

${uscore//_/ }すべて_をスペースで置き換え(....)、文字列を配列に分割し、${arr[@]^}各要素の最初の文字を大文字に変換してから、printf %s ..すべての要素を次々に出力します。
キャメルケースの文字列を別の変数に保存できます:

printf -v ccase %s "${arr[@]^}"

後で使用/再利用します。例:

printf %s\\n $ccase
ThisIsTheStringToBeConverted

または、とzsh

uscore="this_is_the_string_to_be_converted"
arr=(${(s:_:)uscore})
printf %s "${(C)arr}"
ThisIsTheStringToBeConverted

(${(s:_:)uscore})文字列を_配列に分割し、(C)各要素の最初の文字を大文字にし、printf %s ...すべての要素を次々に出力します。
それを別の変数に保存する(j::)には、要素の結合に使用できます。

ccase=${(j::)${(C)arr}}

後で使用/再利用します:

printf %s\\n $ccase
ThisIsTheStringToBeConverted

8

Perlの方法は次のとおりです。

$ echo "this_is_the_string" | perl -pe 's/(^|_)./uc($&)/ge;s/_//g'
ThisIsTheString

任意の長さの文字列を処理できます。

$ echo "here_is_another_larger_string_with_more_parts" | 
    perl -pe 's/(^|_)./uc($&)/ge;s/_//g'
HereIsAnotherLargerStringWithMoreParts

.文字列の先頭またはアンダースコア((^|_))の後にある任意の文字()に一致し、大文字バージョン()に置き換えuc($&)ます。$&ちょうどマッチしたものは何でも含む特別な変数です。のe最後でs///geは、uc()置換内で式(この場合は関数)を使用でき、行内のすべての出現をg置き換えます。2番目の置換により、アンダースコアが削除されます。


perlといえば、下線付きテキストを「キャメル化」するperlモジュールString :: CamelCaseもあります。
don_crissti

@don_crissti ooh、これにぴったりの音。ありがとう。
テルドン

より短いPerl:perl -pe 's/(^|_)([a-z])/uc($2)/ge'
Isaac

6

正規表現の一致で文字列全体を表す必要はありません-sedには、/g複数の一致を調べて、それぞれを置換できる修飾子があります。

echo "this_is_the_string" | sed 's/_\([a-z]\)/\U\1/g;s/^\([a-z]\)/\U\1/g'

最初の正規表現は_\([a-z]\)-アンダースコアの後の各文字です。2番目の文字列は、文字列の最初の文字と一致します。


3

これは、これまでのところ他のどの製品よりも短くてシンプルだからです。

sed -re "s~(^|_)(.)~\U\2~g"

それは言う:大文字、_または次の文字。大文字と小文字がないため、非文字は変更されません。


1
「すべてをできるだけシンプルにする必要がありますが、シンプルではありません。」- アルバート・アインシュタイン。これは他の答えと同等ではありません。あなたの答えは「FOO_BAR」を「FOOBAR」に変換しますが、他の答えはそのままにします。
スコット

@scottあ、そうだとは思わなかった。
ctrl-alt-delor

1
@Scottそれは望ましい振る舞いではありませんか?理想的にはなるはずですFooBarが、指示に従ってアンダースコアを削除する必要があります。とにかく指示を理解したように。
テルドン

2
(続き)…(3)質問の趣旨は、アンダースコア(_)で示される単語の区切りが大文字小文字の遷移で示されるように、文字列を変換することであることがある程度明らかだと思います。「FOO_BAR」→「FooBar」は正しいかもしれませんが、「FOO_BAR」→「FOOBAR」は明らかに間違っています(ワードブレーク情報が破棄されるため)。(4)同様に、衝突を引き起こすマッピングは、質問の精神に反するようです。たとえば、「DO_SPORTS」と「DOS_PORTS」を同じターゲットに変換する答えは間違っていると思います。
スコット

1
(続き)…(5)衝突を起こさないという精神では、「foo_bar」と「FOO_BAR」は同じものにマッピングすべきではないようです。そのため、「FOO_BAR」→「FooBar」に反対します。(6)大きな問題は名前空間だと思います。Blaiseが生きていたのでPascalでプログラミングしたことはありませんが、C / C ++では、慣例により、主に小文字(snake_caseとCamelCaseを含む)の識別子は一般にコンパイラのドメインですが、大文字の識別子はプリプロセッサのドメイン。だからこそ、OPはALL_CAPS識別子を考慮したくないと思うのです。
スコット

1

perlの場合:

$ echo 'alert_beer_core_hemp' | perl -pe 's/(?:\b|_)(\p{Ll})/\u$1/g'
AlertBeerCoreHemp

これも国際化対応です:

$ echo 'алерт_беер_коре_хемп' | perl -CIO -pe 's/(?:\b|_)(\p{Ll})/\u$1/g'
АлертБеерКореХемп

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.