मूल रखते हुए मैं स्ट्रिंग पर पर्ल प्रतिस्थापन कैसे कर सकता हूं?


180

पर्ल में, मूल अभिव्यक्ति को बदले बिना, एक नियमित अभिव्यक्ति का उपयोग करके स्ट्रिंग पर प्रतिस्थापन करने और मूल्य को एक अलग चर में संग्रहीत करने का एक अच्छा तरीका क्या है?

मैं आमतौर पर स्ट्रिंग को एक नए चर में कॉपी करता हूं, फिर इसे s///रेगेक्स से जोड़ता हूं जो नए स्ट्रिंग पर प्रतिस्थापन करता है, लेकिन मैं सोच रहा था कि क्या ऐसा करने का कोई बेहतर तरीका है?

$newstring = $oldstring;
$newstring =~ s/foo/bar/g;

जवाबों:


257

यह मुहावरा है जिसे मैंने हमेशा मूल बदलने के बिना एक स्ट्रिंग की संशोधित प्रतिलिपि प्राप्त करने के लिए उपयोग किया है:

(my $newstring = $oldstring) =~ s/foo/bar/g;

पर्ल 5.14.0 या बाद में, आप नए /r गैर-विनाशकारी प्रतिस्थापन संशोधक का उपयोग कर सकते हैं :

my $newstring = $oldstring =~ s/foo/bar/gr; 

नोट: उपरोक्त समाधान gभी बिना काम करते हैं। वे किसी अन्य संशोधक के साथ भी काम करते हैं।


6
सख्त उपयोग करें या नहीं। चर का न्यूनतम
स्कोरिंग

मैं सोच रहा था कि क्या ऐसा कुछ my $new = $_ for $old =~ s/foo/bar;काम करेगा?
बेनोइट

2
@Benoit, मेरा मानना ​​है कि आपका मतलब है कि s/foo/bar/ for my $newstring = $oldstring;यह काम करता है, लेकिन यह बहुत अजीब है।
इकेगामी

43

बयान:

(my $newstring = $oldstring) =~ s/foo/bar/g;

जो इसके बराबर है:

my $newstring = $oldstring;
$newstring =~ s/foo/bar/g;

वैकल्पिक रूप से, पर्ल 5.13.2 के रूप में आप /rएक गैर विनाशकारी प्रतिस्थापन करने के लिए उपयोग कर सकते हैं :

use 5.013;
#...
my $newstring = $oldstring =~ s/foo/bar/gr;

3
क्या आप gअपने शीर्ष रेगेक्स में भूल गए ?
मढ़ौरा


10

एक-लाइनर समाधान अच्छे कोड की तुलना में एक शिब्बू के रूप में अधिक उपयोगी है; अच्छे पर्ल कोडर्स इसे जानेंगे और समझेंगे, लेकिन यह दो-लाइन कॉपी-एंड-मॉडिफ़ाइड युगल की तुलना में बहुत कम पारदर्शी और पठनीय है।

दूसरे शब्दों में, ऐसा करने का एक अच्छा तरीका वह तरीका है जो आप पहले से कर रहे हैं। पठनीयता की कीमत पर अनावश्यक सहमति जीत नहीं है।


आह, लेकिन एक पंक्ति संस्करण अनजाने में गलत स्ट्रिंग को संशोधित करने के सवाल में त्रुटि के अधीन नहीं है।
ysth

एक पंक्ति संस्करण, <i> यदि सही ढंग से निष्पादित </ i>, विषय नहीं है, सच है। लेकिन यह एक अलग मुद्दा है।
जोश मिलार्ड

9
आपको लगता है कि यह अनावश्यक रूप से गलत हो सकता है, लेकिन एक बार उपयोग करने के लिए दो बार एक चर नाम टाइप करने के बाद एक बार विफलता की संख्या दोगुनी है। यह उन लोगों के लिए पूरी तरह से पठनीय है जो भाषा जानते हैं, और यह हमारे <i> लर्निंग पर्ल </ i> पाठ्यक्रम में भी है।
brian d foy

1

एक और पूर्व -5.14 समाधान: http://www.perlmonks.org/?node_id=346719 (देखें जैफि पोस्ट)

जैसा कि उनका दृष्टिकोण उपयोग करता है map, यह सरणियों के लिए भी अच्छी तरह से काम करता है, लेकिन mapअस्थायी सरणी का उत्पादन करने के लिए कैस्केडिंग की आवश्यकता होती है (अन्यथा मूल संशोधित किया जाएगा):

my @orig = ('this', 'this sucks', 'what is this?');
my @list = map { s/this/that/; $_ } map { $_ } @orig;
# @orig unmodified

1

मुझे फू और बार से नफरत है .. जो प्रोग्रामिंग में इन गैर वर्णनात्मक शब्दों का सपना देखते थे?

my $oldstring = "replace donotreplace replace donotreplace replace donotreplace";

my $newstring = $oldstring;
$newstring =~ s/replace/newword/g; # inplace replacement

print $newstring;
%: newword donotreplace newword donotreplace newword donotreplace

2
यह मूल से अलग कैसे है? (और मुझे लगता है कि आप चाहते हैं =~ s।)
टेपेइमम

क्लबटिक गलती। उस कोड का वास्तविक आउटपुट हैnewword donotnewword newword donotnewword newword donotnewword
पास्कल

2
देखें ... अगर जोगोटा ने पारंपरिक और परिचित का इस्तेमाल किया होता fooऔर bar, तो उनका जवाब सटीक होता। एक बार फिर से, एक कारण के लिए रीति-रिवाज मौजूद हैं, और सबक केवल कठिन तरीके से सीखे जाते हैं। ;)
जॉन

-1

यदि आप पर्ल के साथ लिखते हैं use strict;, तो आप पाएंगे कि घोषित होने पर भी एक पंक्ति वाक्यविन्यास मान्य नहीं है।

साथ में:

my ($newstring = $oldstring) =~ s/foo/bar/;

आपको मिला:

Can't declare scalar assignment in "my" at script.pl line 7, near ") =~"
Execution of script.pl aborted due to compilation errors.

इसके बजाय, आप जिस वाक्यविन्यास का उपयोग कर रहे हैं, जबकि एक पंक्ति लंबी है, उसे करने के लिए वाक्यविन्यास सही तरीका है use strict;। मेरे लिए, उपयोग use strict;करना अब केवल एक आदत है। मैं इसे स्वचालित रूप से करता हूं। हर किसी को करना चाहिए।

#!/usr/bin/env perl -wT

use strict;

my $oldstring = "foo one foo two foo three";
my $newstring = $oldstring;
$newstring =~ s/foo/bar/g;

print "$oldstring","\n";
print "$newstring","\n";

1
यदि आप use warnings;इसके बजाय -w, आप अधिक नियंत्रण प्राप्त करते हैं: उदाहरण के लिए, यदि आप कोड के ब्लॉक में चेतावनी को अस्थायी रूप से बंद करना चाहते हैं।
ग्लेन जैकमैन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.