आपको एक राज्य के साथ प्रतिस्थापन की आवश्यकता है। मुझे याद है कि एसओ पर इस तरह की समस्याओं के लिए (/ कई?) पूरा समाधान उपलब्ध है।
आगे बढ़ने का एक और तरीका है (1)। अब, मैं 2 चरणों में आगे बढ़ूंगा:
- एक डमी सूची चर जिसे मैं नौकरी करूँगा, गंदे और जटिल चाल के लिए चाहिए
- एक प्रतिस्थापन जहां मैं इस डमी सरणी के लेन को सम्मिलित करता हूं जिसे मैं प्रत्येक मिलान घटना पर भर रहा हूं।
जो देता है:
:let t=[]
:%s/#\zs\d\+\(\.\d\+\)\=\ze/\=len(add(t,1))/g
यदि आप regexes का उपयोग नहीं कर रहे हैं, तो मैं उपयोग कर रहा हूं :h /\zs
और \ze
यह निर्दिष्ट करने के लिए कि मैं किस उप-पैटर्न से मेल खा रहा हूं, तो मैं संभवतः एक डॉट और अन्य अंकों के बाद अंकों की एक श्रृंखला से मेल खाता हूं। यह किसी भी फ्लोटिंग पॉइंट नंबर के लिए बिल्कुल सही नहीं है, लेकिन यह यहाँ पर्याप्त है।
नोट: आपको इसे एक साधारण इंटरफ़ेस के लिए युगल फ़ंक्शन + कमांड में लपेटना होगा। फिर, एसओ / विम ( यहां , यहां , यहां ) पर उदाहरण हैं । आजकल मैं इस चाल को एक कमांड में लपेटने की परवाह नहीं करने के लिए पर्याप्त विम जानता हूं। वास्तव में मैं पहली कोशिश में इस कमांड को लिखने में सक्षम हो जाऊंगा, जबकि मुझे कमांड का नाम याद करने में कई मिनट लगेंगे।
(1) उद्देश्य एक राज्य के बीच प्रतिस्थापन को बनाए रखने में सक्षम होना है, और वर्तमान घटना को कुछ ऐसी स्थिति से बदलना है जो वर्तमान स्थिति पर निर्भर करता है।
हमारे लिए धन्यवाद :s\=
एक संगणना के परिणामस्वरूप कुछ सम्मिलित करने में सक्षम है।
राज्य की समस्या को दूर करता है। या तो हम एक फ़ंक्शन को परिभाषित करते हैं जो एक बाहरी राज्य का प्रबंधन कर रहा है, या हम खुद को एक बाहरी स्थिति को अपडेट करते हैं। C (और संबंधित भाषाओं में), हम कुछ का उपयोग कर सकते हैं जैसे length++
या length+=1
। दुर्भाग्य से, विम स्क्रिप्ट में, +=
बॉक्स से बाहर का उपयोग नहीं किया जा सकता है। इसे :set
या तो साथ या उसके साथ उपयोग करने की आवश्यकता है :let
। इसका मतलब है कि :let length+=1
एक संख्या में वृद्धि हुई है, लेकिन कुछ भी वापस नहीं करता है। हम लिख नहीं सकते :s/pattern/\=(length+=1)
। हमें कुछ और चाहिए।
हमें म्यूटिंग कार्यों की आवश्यकता है। यानी ऐसे कार्य जो उनके इनपुट को बदल देते हैं। हम setreg()
, map()
, add()
और शायद अधिक। चलो उनके साथ शुरू करते हैं।
setreg()
एक रजिस्टर को बदल देता है। उत्तम। हम setreg('a',@a+1)
@Doktor OSwaldo के समाधान के रूप में लिख सकते हैं। और फिर भी, यह पर्याप्त नहीं है। setreg()
एक कार्यविधि की तुलना में अधिक है (हमारे उन लोगों के लिए जो पास्कल, एडा ... जानते हैं)। इसका मतलब यह है कि यह कुछ भी वापस नहीं करता है। दरअसल, यह कुछ लौटाता है। नाममात्र निकास (यानी गैर-अपवादात्मक निकास) हमेशा कुछ वापस करते हैं। डिफ़ॉल्ट रूप से, जब हम कुछ वापस करना भूल जाते हैं, तो 0 लौटाया जाता है - यह अंतर्निहित कार्यों के साथ भी लागू होता है। यही कारण है कि उनके समाधान में प्रतिस्थापन अभिव्यक्ति वास्तव में है \=@a+setreg(...)
। मुश्किल है, है ना?
map()
भी इस्तेमाल किया जा सकता है। यदि हम किसी एकल 0 ( :let single_length=[0]
) के साथ एक सूची से शुरू करते हैं , तो हम इसके लिए धन्यवाद बढ़ा सकते हैं map(single_length, 'v:val + 1')
। फिर हमें नई लंबाई वापस करने की आवश्यकता है। इसके विपरीत setreg()
, map()
इसका उत्परिवर्तित इनपुट लौटाता है। यह एकदम सही है, लंबाई सूची में पहले (और अद्वितीय, और इस तरह से पिछले) स्थिति में संग्रहीत है। प्रतिस्थापन अभिव्यक्ति हो सकती है \=map(...)[0]
।
add()
एक मैं अक्सर आदत से बाहर है (मैं map()
वास्तव में के बारे में सिर्फ हालांकि , और मैं अभी तक उनके संबंधित प्रदर्शन नहीं किया है)। साथ विचार add()
वर्तमान स्थिति के रूप में एक सूची का उपयोग करने, और प्रत्येक प्रतिस्थापन से पहले अंत में कुछ संलग्न करने के लिए है। मैं अक्सर सूची के अंत में नए मूल्य को संग्रहीत करता हूं, और प्रतिस्थापन के लिए इसका उपयोग करता हूं। जैसा कि add()
इसकी उत्परिवर्तित इनपुट सूची भी लौटाती है, हम उपयोग कर सकते हैं \=add(state, Func(state[-1], submatch(0)))[-1]
:। ओपी के मामले में, हमें केवल यह याद रखना होगा कि अब तक कितने मैचों का पता चला है। इस राज्य सूची की लंबाई लौटना पर्याप्त है। इसलिए मेरी \=len(add(state, whatever))
।
perldo
, तो आप इस्तेमाल कर सकते हैं:%perldo s/#\K\d+(\.\d+)?/++$i/ge