2010-07-22 12 views
8

: से अलग पहचानकर्ताओं की एक स्ट्रिंग को देखते हुए, क्या अद्वितीय पहचानकर्ताओं को किसी अन्य स्ट्रिंग में निकालने के लिए नियमित अभिव्यक्ति बनाना संभव है, : से अलग भी?क्या नियमित अभिव्यक्ति स्ट्रिंग से डुप्लिकेट आइटम निकाल सकती है?

नियमित अभिव्यक्ति का उपयोग करके इसे प्राप्त करना कैसे संभव है? मैंने s/(:[^:])(.*)\1/$1$2/g को कोई भाग्य नहीं दिया है, क्योंकि (.*) लालची है और $1 के अंतिम मैच में छोड़ देता है।

उदाहरण: a:b:c:d:c:c:x:c:c:e:e:f देना चाहिए a:b:c:d:x:e:f

नोट: मैं पर्ल में कोडिंग रहा हूँ, लेकिन मैं बहुत ज्यादा इस के लिए एक regex का उपयोग कर की सराहना करेंगे।

+1

क्या आप कृपया जो कुछ खोज रहे हैं उसका एक उदाहरण प्रदर्शित कर सकते हैं, मुझे समझ में नहीं आता है। – Anders

उत्तर

8

नेट जो lookbehind अंदर अनंत पुनरावृत्ति का समर्थन करता है में, आप के लिए

(?<=\b\1:.*)\b(\w+):? 

खोज और रिक्त स्ट्रिंग के साथ सभी मैचों बदल सकते थे।

पर्ल (कम से कम पर्ल 5) केवल निश्चित-लम्बाई lookbehinds का समर्थन करता है, तो आप निम्न (अग्रदर्शी का उपयोग कर, एक आसानी से अलग परिणाम के साथ) की कोशिश कर सकते हैं: आप रिक्त स्ट्रिंग के साथ बदलें यदि यह

\b(\w+):(?=.*\b\1:?) 

, सभी पिछले डुप्लिकेट प्रविष्टि की पुनरावृत्ति हटा दी जाएगी; अंतिम एक रहेगा। तो

a:b:c:d:x:e:f 

के बजाय आप मिलेगा

a:b:d:x:c:e:f 

अगर वह ठीक है, तो आप उपयोग कर सकते हैं

$subject =~ s/\b(\w+):(?=.*\b\1:?)//g; 

स्पष्टीकरण:

पहले regex:

+०१२३५१६४१०६१

(?<=\b\1:.*): जांचें कि क्या आप बैकरेफर नंबर की सामग्री से मेल खा सकते हैं। 1, स्ट्रिंग में कहीं पहले, एक कोलन के बाद।

\b(\w+):?: एक पहचानकर्ता से मिलान करें (शब्द सीमा से अगले :), वैकल्पिक रूप से एक कोलन के बाद।

दूसरा regex:

\b(\w+):: एक पहचानकर्ता और कोलन का मिलान करें।

(?=.*\b\1:?): फिर जांचें कि क्या आप समान पहचानकर्ता से मिल सकते हैं, वैकल्पिक रूप से एक कोलन के बाद, स्ट्रिंग में कहीं आगे।

+0

आउटपुट ऑर्डर मेरे लिए अप्रासंगिक है, इसलिए मैंने इस सवाल में इसका उल्लेख नहीं किया है (शायद मुझे यह उल्लेख करना चाहिए था कि यह अप्रासंगिक था :)। धन्यवाद, यह एक आकर्षण की तरह काम किया! – Tom

+0

कृपया अपना उत्तर अपडेट करें, आपके द्वारा प्रदान किया गया समाधान केवल तभी काम करता है जब शब्द एक-वर्ण लंबा हों। इसके बारे में भी उल्लेख करना भूल गए। एक बेहतर उत्तर 's/\ b (\ w +) होगा: (? =। * \ 1:?) // g' – Tom

+0

@ टॉम: उत्कृष्ट बिंदु। मैंने अपना जवाब अपडेट कर लिया है। बैकरेफर के सामने सीमा सम्मिलन शब्द भी आवश्यक है। –

2

चेक आउट: http://www.regular-expressions.info/duplicatelines.html

हमेशा एक उपयोगी जब किसी भी नियमित अभिव्यक्ति के बारे में सोच साइट।

+1

... लेकिन वास्तव में समस्या पर लागू नहीं है, क्योंकि ये समाधान केवल आसन्न डुप्लिकेट के साथ सौदा करते हैं ... –

0

यदि पहचानकर्ताओं को क्रमबद्ध किया गया है, तो आप lookahead/lookbehind का उपयोग करके इसे करने में सक्षम हो सकते हैं। यदि वे नहीं हैं, तो यह एक रेगेक्स की कम्प्यूटेशनल शक्ति से परे है। अब, सिर्फ इसलिए कि औपचारिक regex के साथ असंभव है इसका मतलब यह नहीं है कि अगर आप कुछ perl विशिष्ट regex सुविधा का उपयोग करते हैं, तो यह असंभव है, लेकिन यदि आप अपने regexes पोर्टेबल रखना चाहते हैं तो आपको चर के समर्थन वाली भाषा में इस स्ट्रिंग का वर्णन करने की आवश्यकता है।

+0

सॉर्टिंग प्रासंगिक नहीं है, मेरा समाधान देखें। –

+0

पर्ल-विशिष्ट विशेषताओं से आपका क्या मतलब है? कैप्चरिंग समूह, बैकरेरेंस, शब्द सीमाएं और लुकहेड बहुत व्यापक रूप से समर्थित हैं। इस चर्चा में उपयोग की जाने वाली सुविधाओं में से एकमात्र जिसे मैं गैर-पोर्टेबल कहूंगा, वह विशेष रूप से असंबद्ध दिखने वाला दिखता है। –

+0

@Tim: मैं कहूंगा कि यह इस अर्थ में प्रासंगिक है कि, यदि पहचानकर्ताओं को क्रमबद्ध किया गया था, तो डुप्लीकेट को समाप्त करना तुच्छ होगा: '/ w \ (+ w =) (: \ 1) + (? =: | $)/$ 1/लूप के दौरान खाली के लिए g' –

1
$str = q!a:b:c:d:c:c:x:c:c:e:e:f!; 

1 while($str =~ s/(:[^:]+)(.*?)\1/$1$2/g); 

say $str 

उत्पादन:

a:b:c:d:x:e:f 
+0

+1, हालांकि मुझे लगता है कि एक और पूर्ण समाधान हो सकता है: 'जबकि {$ str = ~ s/(: [^:] + | [^:] +:) (। *) \ 1 (। *)/$ 1 $ 2 $ 3/g} 'पहला अक्षर जांचने के लिए। – NorthGuard

0

यहां एक अजीब संस्करण है, कोई ज़रूरत नहीं है regex।

$ echo "a:b:c:d:c:c:x:c:c:e:e:f" | awk -F":" '{for(i=1;i<=NF;i++)if($i in a){continue}else{a[$i];printf $i}}' 
abcdxef 

विभाजित पर खेतों ":",, splitted क्षेत्रों के माध्यम से जाना एक सरणी में तत्वों की दुकान। अस्तित्व की जांच करें और यदि मौजूद है, तो छोड़ें। अन्यथा उन्हें प्रिंट करें। आप इसे आसानी से पर्ल कोड में अनुवाद कर सकते हैं।

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