रेग्युलर एक्सप्रेशन, जिन्हें अक्सर regex कहा जाता है, पहली नज़र में किसी गुप्त लिपि जैसे लगते हैं — चिह्नों की एक घनी कतार जिसमें कोई अर्थ ढूँढ़ना कठिन हो। पर इनके पीछे एक बेहद साफ़ विचार है। regex असल में एक छोटी-सी भाषा है जिसका एकमात्र काम है पैटर्न के ज़रिए टेक्स्ट का वर्णन करना। एक बार यह समझ आ जाए कि वे टेक्स्ट को किस तरह पढ़ते हैं, तो उनका रहस्य काफ़ी हद तक छँट जाता है।
एक regex असल में करता क्या है
अपने मूल में हर regex एक प्रश्न है — क्या यह टेक्स्ट इस पैटर्न से मेल खाता है? इंजन टेक्स्ट को बाएँ से दाएँ पढ़ता है और हर स्थिति पर जाँचता है कि पैटर्न वहाँ बैठता है या नहीं। यह कोई जादू नहीं, बल्कि एक क्रमिक, यंत्रवत प्रक्रिया है।
इसीलिए regex को एक नियम-समूह की तरह सोचना उपयोगी है, जिसे इंजन एक-एक करके टेक्स्ट पर परखता है। हर चिह्न इंजन को कोई न कोई निर्देश देता है, और पूरा पैटर्न मिलकर बताता है कि किस तरह का टेक्स्ट स्वीकार्य है।
शाब्दिक वर्ण: सबसे सरल मिलान
regex का सबसे सरल रूप वह है जिसमें केवल सामान्य अक्षर हों। ऐसे पैटर्न ठीक वही टेक्स्ट खोजते हैं जो उनमें लिखा है। अगर पैटर्न में cat लिखा हो, तो इंजन टेक्स्ट में ठीक वही तीन अक्षर इसी क्रम में खोजता है।
यहीं से समझ की शुरुआत होती है। जटिल regex भी अंततः इन्हीं शाब्दिक मिलानों और कुछ विशेष चिह्नों का मेल होते हैं। पहले इस सरल आधार को पकड़ लेना बाक़ी सब समझना आसान कर देता है।
वर्ण-वर्ग: विकल्पों का समूह
अगला क़दम यह है कि किसी एक स्थान पर कई संभव वर्णों की अनुमति दी जाए। वर्ण-वर्ग ठीक यही करते हैं — वे इंजन को बताते हैं कि इस स्थिति पर एक तय समूह में से कोई भी वर्ण स्वीकार्य है। मसलन कोई वर्ग किसी एक अंक या किसी एक अक्षर का प्रतिनिधित्व कर सकता है।
यह विचार regex को लचीला बनाता है। अब पैटर्न किसी एक तय शब्द के बजाय वर्णों के एक वर्ग का वर्णन कर सकता है, जिससे वह कई मिलते-जुलते इनपुट को पकड़ लेता है। यही लचीलापन regex की असली शक्ति की पहली झलक है।
परिमाणक: कितनी बार दोहराना है
अकेले वर्ण और वर्ग काफ़ी नहीं; अक्सर हमें यह बताना होता है कि कोई चीज़ कितनी बार दोहराई जा सकती है। परिमाणक यानी क्वांटिफ़ायर यही काम करते हैं — वे बताते हैं कि पिछला हिस्सा शून्य बार, एक बार, या कई बार आ सकता है। इन्हीं की मदद से regex परिवर्तनशील लंबाई के टेक्स्ट का वर्णन कर पाता है।
परिमाणक regex को सचमुच शक्तिशाली बनाते हैं, पर साथ ही सबसे बड़ी उलझन की जड़ भी हैं। लालची परिमाणक जितना संभव हो उतना मिलाने की कोशिश करते हैं, और यही व्यवहार आगे चलकर अप्रत्याशित मिलान या प्रदर्शन-समस्याओं का कारण बन सकता है।
लंगर और सीमाएँ: कहाँ मिलान हो
कभी-कभी यह मायने रखता है कि मिलान कहाँ होता है — पंक्ति की शुरुआत में, अंत में, या किसी शब्द-सीमा पर। लंगर यानी एंकर इंजन को यही बताते हैं। वे कोई वर्ण नहीं मिलाते, बल्कि एक स्थिति की शर्त रखते हैं।
यह भेद महत्वपूर्ण है। बिना लंगर के एक पैटर्न टेक्स्ट के किसी भी हिस्से में बैठ सकता है, जो अक्सर अनचाहे मिलान दे देता है। लंगर पैटर्न को बाँधकर उसे ठीक उसी जगह केंद्रित कर देते हैं जहाँ हमें चाहिए।
समूह और विकल्प: संरचना और शाखाएँ
बड़े पैटर्न में अक्सर ज़रूरत होती है कि कुछ हिस्सों को एक इकाई की तरह समेटा जाए, या कई संभावनाओं में से किसी एक को चुना जाए। समूह कई वर्णों को एक इकाई में बाँध देते हैं, जिससे परिमाणक या विकल्प उस पूरी इकाई पर लागू हो सकें। विकल्प इंजन को कई रास्तों में से किसी एक को आज़माने देते हैं।
यही संरचना regex को छोटे टुकड़ों से बड़े पैटर्न बनाने देती है। पर यही जगह है जहाँ पैटर्न जल्दी जटिल हो जाते हैं, और इसी कारण इन्हें पठनीय रखना एक अलग कौशल है, जिस पर आगे बात होगी।
लालची और संयमी मिलान का फ़र्क़
परिमाणक के व्यवहार में एक सूक्ष्म पर अहम भेद है। कुछ परिमाणक स्वभाव से लालची होते हैं — वे जितना संभव हो उतना मिलाने की कोशिश करते हैं, और ज़रूरत पड़ने पर ही पीछे हटते हैं। दूसरी ओर संयमी परिमाणक न्यूनतम मिलाने की कोशिश करते हैं और केवल आवश्यक होने पर ही और आगे बढ़ते हैं।
यह भेद व्यवहार में बड़ा अंतर ला सकता है। एक लालची पैटर्न अक्सर अपेक्षा से कहीं अधिक टेक्स्ट निगल जाता है, जिससे अनचाहे मिलान आते हैं। जो डेवलपर इस भेद को नहीं जानता, वह अक्सर हैरान रहता है कि उसका पैटर्न आधे की जगह पूरी पंक्ति क्यों पकड़ रहा है।
इस व्यवहार को समझ लेना regex की कई आम उलझनों को सुलझा देता है। जब कोई पैटर्न ज़रूरत से ज़्यादा मिला रहा हो, तो अक्सर समाधान लालची परिमाणक को संयमी बनाने या पैटर्न को अधिक सटीक करने में होता है।
एक मानसिक मॉडल जो regex को कम डरावना बनाता है
इन सब हिस्सों को साथ रखकर देखें, तो regex को समझने का सबसे अच्छा तरीक़ा यही है कि इंजन की तरह सोचा जाए। कल्पना करें कि एक पाठक टेक्स्ट पर बाएँ से दाएँ चल रहा है, हर स्थिति पर पैटर्न के नियम परख रहा है, कभी आगे बढ़ रहा है तो कभी पीछे लौटकर कोई दूसरा रास्ता आज़मा रहा है।
इस मानसिक मॉडल के साथ अपरिचित regex भी पढ़ने योग्य हो जाते हैं। आप उन्हें एक साथ देखने के बजाय टुकड़ों में बाँटकर देख सकते हैं, हर हिस्से से पूछ सकते हैं कि वह इंजन को क्या कहता है, और इस तरह सबसे डरावने दिखने वाले पैटर्न भी एक तर्कसंगत क्रम में खुलने लगते हैं।