2010-03-18 13 views
12

मेरा $ str = "1: 2: 3: 4: 5"; मेरा ($ ए, $ बी) = विभाजन (':', $ str, 2);मैं विभाजक की आखिरी घटना पर केवल एक पर्ल स्ट्रिंग कैसे विभाजित कर सकता हूं?

उपरोक्त कोड में मैंने सीमा 2 का उपयोग किया है, इसलिए $ 1 में 1 होगा और शेष तत्व $ बी में होंगे। इस तरह मैं चाहता हूं कि अंतिम तत्व एक चर में होना चाहिए और अंतिम तत्व से पहले तत्व किसी अन्य चर में होना चाहिए।

उदाहरण

$str = "1:2:3:4:5" ; 
# $a should have "1:2:3:4" and $b should have "5" 
$str = "2:3:4:5:3:2:5:5:3:2" 
# $a should have "2:3:4:5:3:2:5:5:3" and $b should have "2" 
+1

डुप्लिकेट: http://stackoverflow.com/questions/1098295/perl-is-there-a-way-to-split-on-the-last-regex -मैच-केवल – Zaid

उत्तर

2

आप विभाजन का उपयोग कर ऐसा कर सकते हैं और इस प्रकार रिवर्स:

my $str="1:2:3:4:5"; 
my ($a,$b)=split(':',reverse($str),2); # reverse and split. 

$a = reverse($a); # reverse each piece. 
$b = reverse($b); 

($a,$b) = ($b,$a); # swap a and b 

अब $a1:2:3:4 हो जाएगा और $b5 हो जाएगा।

मार्क ने अपने उत्तर में किए गए रेगेक्स का उपयोग करने के लिए एक बहुत ही सरल और साफ तरीका है।

+1

हालांकि यह एक संभावना है, यह बिल्कुल कुशल नहीं है, खासकर जब एक पंक्ति समकक्ष करेगी। कुछ 'मेरा ($ ए, $ बी) = ($ str = ~ /(.*):(.?)/); ' – Zaid

7

आप भी उपयोग कर सकते हैं rindex() जैसे

my $str="1:2:3:4:5"; 
$i=rindex($str,":"); 
$a=substr($str,0,$i); 
$b=substr($str,$i+1); 
print "\$a:$a, \$b: $b\n"; 

उत्पादन

$ perl perl.pl 
$a:1:2:3:4, $b: 5 
+0

चूंकि विभाजित विभाजक इस मामले में इतना आसान है, यह उपयोग करने से एक तेज़ समाधान है पूरी अभिव्यक्ति के माध्यम से '$ 'से जुड़ने की कोशिश कर रहे एक अभिव्यक्ति के माध्यम से पार्स करने के लिए एक regex। – Ether

6

आप विभाजन के बजाय, मिलान का उपयोग कर सकते हैं:

my ($a,$b) = $str =~ /(.*):(.*)/; 
+0

मैं यह सुनिश्चित करने के लिए उस दूसरे '। *' '' '? 'बनाउंगा। – Zaid

2

मुझे पता है, इस सवाल का 4 साल पुराना है । लेकिन मुझे YOU से बहुत रोचक मिला क्योंकि मुझे पता नहीं था कि split ऐसा काम कर सकता है। इसलिए मैं इसे perldoc split से निकालने के साथ विस्तारित करना चाहता हूं जो नए पाठकों के लिए इस व्यवहार को समझाता है। :-)

my $str = "1:2:3:4:5"; 
my ($a, $b) = split /:([^:]+)$/, $str; 
# Capturing everything after ':' that is not ':' and until the end of the string 
# Now $a = '1:2:3:4' and $b = '5'; 

Perldoc से:

पद्धति शामिल समूहों पर कब्जा, तो प्रत्येक विभाजक के लिए, एक अतिरिक्त क्षेत्र प्रत्येक स्ट्रिंग एक समूह द्वारा कब्जा कर लिया के लिए (उत्पादन किया जाता है, तो क्रम में जिसमें समूहों को बैक्रेरेंस के अनुसार निर्दिष्ट किया गया है); यदि कोई समूह मेल नहीं खाता है, तो यह एक सबस्ट्रिंग के बजाय अपरिष्कृत मूल्य को कैप्चर करता है। साथ ही, ध्यान दें कि कोई भी अतिरिक्त क्षेत्र तब भी उत्पादित होता है जब कोई विभाजक होता है (यानी, जब भी कोई विभाजन होता है), और ऐसा अतिरिक्त फ़ील्ड LIMIT की ओर गिनती नहीं करता है। सूची संदर्भ में मूल्यांकन निम्न भाव पर विचार करें (प्रत्येक लौटे सूची जुड़े टिप्पणी में प्रदान की जाती है):

split(/-|,/, "1-10,20", 3) 
# ('1', '10', '20') 

split(/(-|,)/, "1-10,20", 3) 
# ('1', '-', '10', ',', '20') 

split(/-|(,)/, "1-10,20", 3) 
# ('1', undef, '10', ',', '20') 

split(/(-)|,/, "1-10,20", 3) 
# ('1', '-', '10', undef, '20') 

split(/(-)|(,)/, "1-10,20", 3) 
# ('1', '-', undef, '10', undef, ',', '20') 
0

मैं थोड़ा इस सवाल का देर हो रही है, लेकिन मैं एक साथ एक अधिक सामान्य समाधान कर दिया:

# Similar to split() except pattern is applied backwards from the end of the string 
# The only exception is that the pattern must be a precompiled regex (i.e. qr/pattern/) 
# Example: 
# rsplit(qr/:/, 'John:Smith:123:ABC', 3) => ('John:Smith', '123', 'ABC') 
sub rsplit { 
    my $pattern = shift(@_); # Precompiled regex pattern (i.e. qr/pattern/) 
    my $expr = shift(@_); # String to split 
    my $limit = shift(@_); # Number of chunks to split into 

    # 1) Reverse the input string 
    # 2) split() it 
    # 3) Reverse split()'s result array element order 
    # 4) Reverse each string within the result array 
    map { scalar reverse($_) } reverse split(/$pattern/, scalar reverse($expr), $limit); 
} 

यह split() के समान तर्क स्वीकार करता है सिवाय इसके कि विभाजन रिवर्स ऑर्डर में किया जाता है। यदि आपको किसी निर्दिष्ट संख्या के परिणाम तत्वों की आवश्यकता होती है तो यह एक सीमा खंड भी स्वीकार करता है।

नोट: यह सबराउटिन पहले पैरामीटर के रूप में precompiled regex की अपेक्षा करता है।
पर्ल के split एक अंतर्निहित है और सही ढंग से /pat/ व्याख्या करेगा, लेकिन एक सबरूटीन sub($_ =~ /pat/) रूप में माना जाएगा करने के लिए /pat/ पारित करने के लिए प्रयास करते हैं।

यह सबराउटिन बुलेटप्रूफ नहीं है! यह सरल delimiters के लिए काफी अच्छी तरह से काम करता है लेकिन अधिक जटिल पैटर्न मुद्दों का कारण बन सकता है। पैटर्न को उलट नहीं किया जा सकता है, केवल अभिव्यक्ति जो इसके खिलाफ मेल खाती है।


उदाहरण:

rsplit(qr/:/, 'One:Two:Three', 2); # => ('One:Two', 'Three') 

rsplit(qr/:+/, 'One:Two::Three:::Four', 3); # => ('One:Two', 'Three', 'Four') 

# Discards leading blank elements just like split() discards trailing blanks 
rsplit(qr/:/, ':::foo:bar:baz'); # => ('foo', 'bar', 'baz') 
संबंधित मुद्दे

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