अपरकेस को PascalCase में बदलें, अर्थात अपरकंपेलकेस


28

अगर मेरे पास एक तार है जो इस तरह दिखता है:

"this_is_the_string"

बैश स्क्रिप्ट के अंदर, मैं इसे PascalCase में बदलना चाहूंगा, अर्थात अपरकैमेलकैसे इस तरह दिखना:

"ThisIsTheString"

मैंने पाया कि लोअरकैमेलकेस में कनवर्ट करना इस तरह से किया जा सकता है:

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

दुर्भाग्य से मैं इसे संशोधित करने के लिए रेगेक्स से पर्याप्त परिचित नहीं हूं।


(1) यह वास्तव में कोई फर्क नहीं पड़ता, जहां तक ​​यह सवाल (और अब तक प्रस्तुत जवाब) चिंतित हैं, लेकिन, FYI करें, \U\2दूसरे समूह से पाया गया पाठ सम्मिलित करता है, ALL CAPS में परिवर्तित हो जाता है। इसकी तुलना करें \u\2, जो कि पाठ को वाक्य के मामले में सम्मिलित करता है, जिसमें केवल पहला वर्ण कैपिटल होता है। (२) नीचे दिए गए सभी उदाहरण "This_is_a_string" को "ThisIsAString" में अनुवाद करेंगे - जो आपने पूछा है, लेकिन पढ़ने में थोड़ा कठिन है। आप एक-अक्षर के शब्द (विकल्प) के विशेष मामले के लिए अपनी आवश्यकताओं को संशोधित करना चाह सकते हैं। … (Cont'd)
स्कॉट

(Cont'd)… (3) क्या आपके पास प्रति पंक्ति केवल एक ही स्ट्रिंग है? और क्या यह लाइन पर हमेशा पहला (या एकमात्र ) पाठ है? यदि आपके पास एक स्ट्रिंग है जो लाइन की शुरुआत में नहीं है, तो नीचे दिए गए उत्तर इसे लोअरकेमसेलकैसे में बदल देंगे। ठीक करने के लिए, जैनिस का जवाब लें और बदल (^|_)दें (\<|_)
स्कॉट

जवाबों:


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


(^|_)स्ट्रिंग की शुरुआत में या एक अंडरस्कोर के बाद सबस्टिट्यूट पैटर्न - पहला समूह
([a-z])सिंगल लोअर केस लेटर - दूसरा ग्रुप विश्व स्तर पर दूसरे ग्रुप
को
\U\2अपरकेस करके
g


4
नोट: \UPOSIX के लिए एक GNU एक्सटेंशन है।
सिरो सेंटिल्ली 新疆 改造 iro 六四 事件

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

यहाँ एक पर्ल तरीका है:

$ 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इसकी जगह बनाता है सभी लाइन में घटनाओं। दूसरा प्रतिस्थापन अंडरस्कोर हटाता है।


पर्ल की बात करें तो, एक पर्ल मॉड्यूल स्ट्रिंग है :: CamelCase जो अंडरस्क्राइब्ड टेक्स्ट को "कैमलाइज" करता है।
don_crissti

@don_crissti ओह, इसके लिए एकदम सही लगता है। धन्यवाद।
terdon

शॉर्टर पर्ल:perl -pe 's/(^|_)([a-z])/uc($2)/ge'
आइज़ैक

6

यह नियमित अभिव्यक्ति मैच में पूरे स्ट्रिंग का प्रतिनिधित्व करने के लिए आवश्यक नहीं है - sed में /gसंशोधक है जो आपको कई मैचों में चलने और उनमें से प्रत्येक को बदलने की अनुमति देता है:

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

पहला रेगेक्स है _\([a-z]\)- अंडरस्कोर के बाद प्रत्येक अक्षर; दूसरा एक स्ट्रिंग में पहले अक्षर से मेल खाता है।


3

मैं केवल इस जवाब में डालता हूं क्योंकि यह अब तक किसी भी अन्य की तुलना में छोटा और सरल है।

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

यह कहता है: ऊपर, एक _या शुरुआत के बाद चरित्र । गैर पत्र नहीं बदले जाएंगे, क्योंकि उनके पास कोई मामला नहीं है।


1
"सब कुछ जितना संभव हो उतना सरल बनाया जाना चाहिए, लेकिन सरल नहीं।" - अल्बर्ट आइंस्टीन। यह अन्य उत्तरों के बराबर नहीं है; आपका उत्तर "FOO_BAR" को "FOOBAR" में बदल देगा, जबकि अन्य उत्तर इसे अकेले छोड़ देंगे।
स्कॉट

@sc आह हां, मैंने ऐसा नहीं सोचा था।
ctrl-alt-delor-

1
@Scott वांछित व्यवहार नहीं है? मुझे लगता है कि आदर्श रूप से, यह बनना चाहिए FooBarलेकिन निर्देश के अनुसार अंडरस्कोर को हटा दिया जाना चाहिए। जैसा कि मैं वैसे भी निर्देशों को समझता हूं।
terdon

2
(Cont'd) ... (3) मुझे लगता है कि यह कुछ हद तक स्पष्ट है कि प्रश्न की भावना एक स्ट्रिंग को बदलने के लिए है ताकि अंडरस्कोर ( _) द्वारा इंगित शब्द विराम को मामले के संक्रमण द्वारा इंगित किया जाए। यह देखते हुए कि, "FOO_BAR" → "FOOBAR" स्पष्ट रूप से गलत है (क्योंकि यह शब्द ब्रेक की जानकारी देता है), हालांकि "FOO_BAR" → "FooBar" सही हो सकता है। (४) इसी प्रकार, एक मानचित्रण जो टकराव का कारण बनता है, प्रश्न की भावना के विपरीत प्रतीत होता है। उदाहरण के लिए, मेरा मानना ​​है कि एक उत्तर जो "DO_SPORTS" और "DOS_PORTS" को एक ही लक्ष्य में परिवर्तित करता है, गलत है।
स्कॉट

1
(फिर से शामिल करें)… (5) टकराव पैदा न करने की भावना में, यह मुझे लगता है कि “foo_bar” और “FOO_BAR” को एक ही चीज़ के लिए मैप नहीं करना चाहिए, इसलिए मुझे “FOO_BAR” → FooBar पर आपत्ति है। । (६) मुझे लगता है कि बड़ा मुद्दा नाम स्थान है। ब्लेक जीवित होने के बाद से मैंने पास्कल में प्रोग्राम नहीं किया है, लेकिन सी / सी ++ में, कन्वेंशन द्वारा, पहचानकर्ता जो मुख्य रूप से निचले मामले में हैं (स्नेककेस और कैमलकेज़ को शामिल करने के लिए) आम तौर पर कंपाइलर का डोमेन हैं, जबकि ऊपरी मामले में पहचानकर्ता हैं। प्री-प्रोसेसर का डोमेन। इसलिए मुझे लगता है कि ओपी नहीं चाहता था कि ALL_CAPS पहचानकर्ताओं पर विचार किया जाए।
स्कॉट

1

पर्ल में:

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

यह भी i18n-सक्षम है:

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.