2010-10-22 7 views
27

मेरे पास ImageWideNice या ImageNarrowUgly जैसी अच्छी कैमलकेस स्ट्रिंग है। अब मैं उस स्ट्रिंग को अपने सबस्ट्रिंग्स में तोड़ना चाहता हूं, जैसे Image, Wide या Narrow, और Nice या Uglyरूबी में अपने सबस्ट्रिंग में कैमलकेस स्ट्रिंग को कैसे विभाजित करें?

मैंने सोचा था कि यह बस द्वारा

camelCaseString =~ /(Image)((Wide)|(Narrow))((Nice)|(Ugly))/ 

लेकिन अजीब हल किया जा सकता, यह केवल $1 और $2, लेकिन नहीं $3 भर जाएगा।

क्या आपके पास उस स्ट्रिंग को विभाजित करने के लिए एक बेहतर विचार है?

+1

आप'IIsanarrowImageOfHIV 'के साथ क्या करना चाहते हैं? एन के साथ जुड़ें या एचआईवी को विभाजित करें? –

उत्तर

50
s = 'nowIsTheTime' 

s.split /(?=[A-Z])/ 

=> ["now", "Is", "The", "Time"] 

?=patternसकारात्मक अग्रदर्शी का एक उदाहरण है। यह अनिवार्य रूप से पैटर्न से पहले स्ट्रिंग में एक बिंदु से मेल खाता है। यह वर्णों का उपभोग नहीं करता है, यानी, इसमें मैच के हिस्से के रूप में पैटर्न शामिल नहीं है। एक और उदाहरण:

irb> 'streets'.sub /t(?=s)/, '-' 
=> "stree-s" 

इस मामले s में मिलान किया जाता है (केवल दूसरे t मैचों), लेकिन नहीं बदला। धन्यवाद करने के लिए @Bryce और उसके regexp doc link. ब्राइस एंडरसन एक विवरण जोड़ता है:

?=() मैच समूह की शुरुआत में सकारात्मक अग्रदर्शी कहा जाता है, जो सिर्फ कह रही है कि, जबकि regex है की तलाश का एक तरीका है यह निर्धारित करने में वर्णों पर कि यह मेल खाता है, यह नहीं है जो उन्हें मैच का हिस्सा बना रहा है। split() आमतौर पर वर्णों के बीच खाता है, लेकिन इस मामले में मैच स्वयं खाली है, इसलिए कुछ भी नहीं है [वहां]।

+1

क्या आपने 'NowIsTheTime' की कोशिश की है? – splash

+1

@ स्प्लैश: यह अभी भी ठीक काम करता है – ryeguy

+0

मेरे परीक्षणों के दौरान इस रेगेक्स के परिणाम '["", "अब", "है", "द", "टाइम"] में होते हैं,' यदि पहला अक्षर एक अपरकेस अक्षर है। मैं क्या गलत हूँ? – splash

2

आप

camelCaseString =~ /(Image)(Wide|Narrow)(Nice|Ugly)/ 

की कोशिश की है?

2

घटना हालांकि यह एक रूबी regex सवाल यह है कि और answer by DigitalRoss सही है और अपनी सादगी से चमकता है, मैं एक जावा जवाब जोड़ना चाहते हैं:

// this regex doesn't work perfect with Java and other regex engines 
"NowIsTheTime".split("(?=[A-Z])"); // ["", "Now", "Is", "The", "Time"] 

// this regex works with first uppercase or lowercase characters 
"NowIsTheTime".split("(?!(^|[a-z]|$))"); // ["Now", "Is", "The", "Time"] 
"nowIsTheTime".split("(?!(^|[a-z]|$))"); // ["now", "Is", "The", "Time"] 
27

मैं जानता हूँ कि यह पुराना है, लेकिन दूसरों के लिए उल्लेख के लायक है जो शायद इसकी तलाश हो रही है। रेल में आप यह कर सकते हैं: "NowIsTheTime".underscore.humanize

5

डिजिटलरॉस का जवाब सही है क्योंकि यह सामान्य मामला संभालता है जहां आप नहीं जानते कि यह सख्त ऊंट का मामला है (पहला चरित्र लोअर केस) या पास्कल केस (पहला अक्षर ऊपरी मामला)।

यदि आप जानते हैं कि इनमें से कौन से रूप स्ट्रिंग में हैं, या आप एक या दूसरे को मजबूर करना चाहते हैं, तो इन्फ्लिक्टर इसे कर सकता है।

पास्कल मामले के लिए:

"NowIsTheTime".titleize 

ऊंट मामले के लिए:

"nowIsTheTime".titleize.camelize :lower 
+0

ध्यान देने योग्य महत्वपूर्ण है, '# शीर्षक' और '# camelize' कड़ाई से रेल विधियां हैं, न कि कोर रूबी में। – onebree

0

DigitalRoss से जवाब केमलकेस में एम्बेडेड के संक्षिप्त रूप को पहचान नहीं होगा। उदाहरण के लिए, यह "माई एचटीएमएल ट्रिक्स" को "माई एच टी एम एल ट्रिक्स" में "माई एच टी एम एल ट्रिक्स" में विभाजित करेगा।

कि
"MyHTMLTricks" \ 
.gsub(/([[:lower:]\\d])([[:upper:]])/, '\1 \2') \ 
.gsub(/([^-\\d])(\\d[-\\d]*(|$))/,'\1 \2') \ 
.gsub(/([[:upper:]])([[:upper:]][[:lower:]\\d])/, '\1 \2') 

=> "My HTML Tricks" 

दूसरी बात यह है कि मैं इस दृष्टिकोण के बारे में की तरह है यह स्ट्रिंग छोड़ देता है:

यहाँ PmWiki में AsSpaced() कार्य के आधार पर एक और विकल्प है, जो इस तरह के मामलों के प्रति संवेदनशील होने का एक बहुत अच्छा काम करता है एक स्ट्रिंग, इसे एक सरणी में बदलने की बजाय। यदि आप वास्तव में सरणी चाहते हैं, तो बस अंत में एक विभाजन जोड़ें।

"MyHTMLTricks" \ 
.gsub(/([[:lower:]\\d])([[:upper:]])/, '\1 \2') \ 
.gsub(/([^-\\d])(\\d[-\\d]*(|$))/,'\1 \2') \ 
.gsub(/([[:upper:]])([[:upper:]][[:lower:]\\d])/, '\1 \2') \ 
.split 

=> ["My", "HTML", "Tricks"] 

रिकॉर्ड के लिए, यहां PmWiki से मूल PHP कोड है।

function AsSpaced($text) { 
    $text = preg_replace("/([[:lower:]\\d])([[:upper:]])/", '$1 $2', $text); 
    $text = preg_replace('/([^-\\d])(\\d[-\\d]*(|$))/', '$1 $2', $text); 
    return preg_replace("/([[:upper:]])([[:upper:]][[:lower:]\\d])/", '$1 $2', $text); 
} 
संबंधित मुद्दे

 संबंधित मुद्दे