दिलचस्प पोस्ट
एक्लिप्स निर्यात किए गए रननबल जार छवियों को प्रदर्शित नहीं करते WooCommerce आदेश विवरण कैसे प्राप्त करें सेलेनियम के साथ इंडेक्स द्वारा Xpath नोड सेट के भीतर निर्दिष्ट नोड कैसे चुनना है? एप्लिकेशन फ़ोल्डर पथ प्राप्त करने का सर्वोत्तम तरीका क्या एचटीएमएलए वेब पृष्ठों को पीअर-टू-पीयर एचटीटीपी कनेक्शन बनाने की अनुमति देगा? रूबी के सेटर्स को कक्षा में "आत्म" योग्यता की आवश्यकता क्यों है? MKAnnotationView के लिए कॉलआउट बबल को कैसे अनुकूलित करें? इंटरफ़ेस बनाम सार कक्षा (सामान्य ओ ओ) सी में वस्तु उन्मुखीकरण कस्टम कॉन्फ़िगरेशन फ़ाइलें लोड हो रही हैं वेबसाकेट प्रोटोकॉल बनाम HTTP मैं जावा में स्विंगवॉकर का उपयोग कैसे करूं? क्या सभी पायथन कक्षाएं ऑब्जेक्ट को बढ़ाती हैं? "अवैध पैरामीटर संख्या: पैरामीटर परिभाषित नहीं किया गया था" डेटा डालने पायथन 'के लिए' लूप में सूचकांक तक पहुंचना

पर्ल प्रतिस्थापन ऑपरेटर के प्रतिस्थापन पक्ष में एक चर का उपयोग कैसे करें?

मैं निम्नलिखित करना चाहता हूं:

$find="start (.*) end"; $replace="foo \1 bar"; $var = "start middle end"; $var =~ s/$find/$replace/; 

मैं $ var को "फ़ू मिडल बार" शामिल करने की उम्मीद करता हूं, लेकिन यह काम नहीं करता। न तो करता है:

 $replace='foo \1 bar'; 

किसी तरह मुझे बचने के बारे में कुछ याद आ रही है


मैंने तय किया कि लापता है '

वेब के समाधान से एकत्रित समाधान "पर्ल प्रतिस्थापन ऑपरेटर के प्रतिस्थापन पक्ष में एक चर का उपयोग कैसे करें?"

प्रतिस्थापन पक्ष पर, आपको $ 1 का उपयोग करना चाहिए, नहीं \ 1

और आप केवल वही कर सकते हैं जो आप चाहते हैं कि आप जो एक्स्ट्रालेबल अभिव्यक्ति चाहते हैं, जो आपको चाहते हैं और s /// को कहें, जैसे इसे / ee संशोधक के साथ eval करें:

 $find="start (.*) end"; $replace='"foo $1 bar"'; $var = "start middle end"; $var =~ s/$find/$replace/ee; print "var: $var\n"; 

देखने के लिए कि "" और डबल / ई क्यों जरूरी है, यहां डबल इवल का प्रभाव देखें:

 $ perl $foo = "middle"; $replace='"foo $foo bar"'; print eval('$replace'), "\n"; print eval(eval('$replace')), "\n"; __END__ "foo $foo bar" foo middle bar 

Deparse हमें बताता है कि यह क्या किया जा रहा है:

 $find = 'start (.*) end'; $replace = "foo \cA bar"; $var = 'start middle end'; $var =~ s/$find/$replace/; 

तथापि,

  /$find/foo \1 bar/ 

के रूप में व्याख्या की है:

 $var =~ s/$find/foo $1 bar/; 

दुर्भाग्य से ऐसा प्रतीत होता है कि ऐसा करने का कोई आसान तरीका नहीं है।

आप इसे स्ट्रिंग eval के साथ कर सकते हैं, लेकिन यह खतरनाक है

सबसे समझदार समाधान जो मेरे लिए काम करता है वह यह था:

 $find = "start (.*) end"; $replace = 'foo \1 bar'; $var = "start middle end"; sub repl { my $find = shift; my $replace = shift; my $var = shift; # Capture first my @items = ( $var =~ $find ); $var =~ s/$find/$replace/; for( reverse 0 .. $#items ){ my $n = $_ + 1; # Many More Rules can go here, ie: \g matchers and \{ } $var =~ s/\\$n/${items[$_]}/g ; $var =~ s/\$$n/${items[$_]}/g ; } return $var; } print repl $find, $replace, $var; 

ईई तकनीक के खिलाफ एक खंडन:

जैसा कि मैंने अपने जवाब में कहा था, मैं एक कारण से evals से बचने के लिए

 $find="start (.*) end"; $replace='do{ print "I am a dirty little hacker" while 1; "foo $1 bar" }'; $var = "start middle end"; $var =~ s/$find/$replace/ee; print "var: $var\n"; 

यह कोड वास्तव में आपको लगता है कि ऐसा करता है।

यदि आपकी प्रतिस्थापन स्ट्रिंग वेब अनुप्रयोग में है, तो आपने आधिकारिक कोड निष्पादन के लिए दरवाजा खोल दिया है।

बहुत बढ़िया।

इसके अलावा, यह इस कारण के लिए तेंदुओं के साथ काम नहीं करेगा

 $find="start (.*) end"; $replace='"' . $ARGV[0] . '"'; $var = "start middle end"; $var =~ s/$find/$replace/ee; print "var: $var\n" $ perl /tmp/re.pl 'foo $1 bar' var: foo middle bar $ perl -T /tmp/re.pl 'foo $1 bar' Insecure dependency in eval while running with -T switch at /tmp/re.pl line 10. 

हालांकि, अधिक सतर्क तकनीक समझदार, सुरक्षित, सुरक्षित है, और दाग को विफल नहीं करता है। (आश्वस्त रहें, यह उत्सर्जित स्ट्रिंग अभी भी दूषित है, इसलिए आप किसी भी सुरक्षा को नहीं खोना चाहते हैं।)

 # perl -de 0 $match="hi(.*)" $sub='$1' $res="hi1234" $res =~ s/$match/$sub/gee p $res 1234 

सावधान रहें, यद्यपि। इससे ईलाई के दो परतों का कारण बनता है, regex के अंत में प्रत्येक e लिए एक:

  1. $ उप -> $ 1
  2. $ 1 -> अंतिम मूल्य, उदाहरण के लिए, 1234

जैसा कि अन्य लोगों ने सुझाव दिया है, आप निम्न का उपयोग कर सकते हैं:

 my $find = 'start (.*) end'; my $replace = 'foo $1 bar'; # 'foo \1 bar' is an error. my $var = "start middle end"; $var =~ s/$find/$replace/ee; 

उपरोक्त निम्नलिखित के लिए कम है:

 my $find = 'start (.*) end'; my $replace = 'foo $1 bar'; my $var = "start middle end"; $var =~ s/$find/ eval($replace) /e; 

मैं पहली बार दूसरे को पसंद करता हूं क्योंकि यह इस तथ्य को नहीं छिपाता है कि eval(EXPR) का उपयोग किया जाता है हालांकि, ऊपर की चुप्पी त्रुटियों में से दोनों, इसलिए निम्नलिखित बेहतर होगा:

 my $find = 'start (.*) end'; my $replace = 'foo $1 bar'; my $var = "start middle end"; $var =~ s/$find/ my $r = eval($replace); die $@ if $@; $r /e; 

लेकिन जैसा कि आप देख सकते हैं, उपर्युक्त सभी मनमाने ढंग से पर्ल कोड के निष्पादन के लिए अनुमति देते हैं। निम्नलिखित से कहीं अधिक सुरक्षित होगा:

 use String::Substitution qw( sub_modify ); my $find = 'start (.*) end'; my $replace = 'foo $1 bar'; my $var = "start middle end"; sub_modify($var, $find, $replace); 

मैं कुछ सुझाव देता हूं:

 $text =~ m{(.*)$find(.*)}; $text = $1 . $replace . $2; 

यह काफी पठनीय है और सुरक्षित लगता है यदि एकाधिक प्रतिस्थापन की आवश्यकता है, तो यह आसान है:

 while ($text =~ m{(.*)$find(.*)}){ $text = $1 . $replace . $2; } 

पर्ल में s/// के प्रतिस्थापन पक्ष पर एक चर का उपयोग करते हुए इस पिछले SO पोस्ट देखें। स्वीकार किए जाते हैं उत्तर और रद्दी उत्तर दोनों पर गौर करें।

आप जो करने की कोशिश कर रहे हैं वह s///ee फॉर्म के साथ संभव है जो दाहिने हाथ की स्ट्रिंग पर एक डबल eval करता है। अधिक उदाहरणों के लिए ऑपरेटर की तरह प्रतिलिपि बोली देखें

चेतावनी दी है कि eval की सुरक्षा impilcations हैं और यह रंग मोड में काम नहीं करेगा

 #!/usr/bin/perl $sub = "\\1"; $str = "hi1234"; $res = $str; $match = "hi(.*)"; $res =~ s/$match/$1/g; print $res 

यह मुझे '1234' मिला

मैं निश्चित नहीं हूं कि आप क्या हासिल करना चाहते हैं। लेकिन शायद आप इसका उपयोग कर सकते हैं:

 $var =~ s/^start/foo/; $var =~ s/end$/bar/; 

Ie सिर्फ अकेले बीच छोड़ और शुरू और अंत की जगह