03 / गाइड
रेगुलर एक्सप्रेशन टेस्ट करने का सुरक्षित वर्कफ़्लो
JavaScript रेगुलर एक्सप्रेशन के लिए लिखें-टेस्ट करें-रिफ़ैक्टर करें का चक्र: यथार्थ सैंपल डेटा, कैटास्ट्रॉफ़िक बैकट्रैकिंग की सफ़ाई, एंकरिंग अनुशासन, फ़्लैग सिमेंटिक्स, और ब्राउज़र में टेस्ट करना पैटर्न निजी क्यों रखता है।
चक्र: लिखें, टेस्ट करें, रिफ़ैक्टर करें
भरोसेमंद रेगेक्स कभी एक बार में नहीं लिखा जाता। एक असली उदाहरण से मेल खाने वाले सबसे छोटे पैटर्न से शुरुआत करें, चलाएँ, फिर अगले उदाहरण के सामने उसे चौड़ा या कसें। सैंपल टेक्स्ट ही विनिर्देश है; पैटर्न कार्यान्वयन है।
Auto-run चालू हो तो टाइपिंग थोड़ी देर रुकने के बाद परीक्षण चलता है, हर कीस्ट्रोक पर नहीं। इससे संपादन और परीक्षण का चक्र तेज़ रहता है।
- सैंपल से शुरू करेंपैटर्न किसी ठोस सैंपल के सामने लिखें, याददाश्त से नहीं: उस लॉग या दस्तावेज़ की असली लाइन पेस्ट करें जिसे आप पार्स करना चाहते हैं।
- हर एडिट टेस्ट करेंहर बदलाव के बाद टेस्ट करें — रेगेक्स में कंपाइलर चेतावनियाँ नहीं होतीं, इसलिए इकलौता फ़ीडबैक यही है कि वह क्या मिलाता है और क्या चूकता है।
- पाठकों के लिए रिफ़ैक्टर करेंपास होने के बाद पठनीयता के लिए रिफ़ैक्टर करें: नामित कैप्चर ग्रुप और नॉन-कैप्चरिंग ग्रुप काम करते पैटर्न को अगले पाठक के लिए सहने योग्य बनाते हैं।
कैटास्ट्रॉफ़िक बैकट्रैकिंग का सम्मान करें
JavaScript का रेगेक्स इंजन बैकट्रैक करता है: मैच विफल होने पर वह हर क्वांटिफ़ायर के लिए अलग लंबाइयों से फिर कोशिश करता है। (a+)+ जैसे नेस्टेड क्वांटिफ़ायर किसी लगभग-मैच स्ट्रिंग पर कोशिशों की संख्या को घातांकीय रूप से फूला देते हैं — अच्छे इनपुट पर तुरंत जवाब देने वाला पैटर्न बुरे इनपुट पर सालों चल सकता है। हमलावर इसे ReDoS कहते हैं।
JavaScript Regex Tester पैटर्न को 650 मिलीसेकंड की सीमा वाले Web Worker में चलाता है और समय सीमा पार होने पर बताता है। वास्तविक नमूने पर ऐसा हो तो उत्पादन में इस्तेमाल होने वाले regex इंजन और इनपुट सीमाओं के साथ दोबारा परीक्षण करें।
- नेस्टेड क्वांटिफ़ायरक्लासिक आकार है क्वांटिफ़ाइड ग्रुप के अंदर क्वांटिफ़ाइड टोकन — (a+)+, (\w+)* — जहाँ एक ही स्ट्रिंग के कई विभाजन भीतरी पैटर्न को संतुष्ट करते हैं।
- अस्पष्ट विकल्पअस्पष्ट विकल्प भी यही करता है: (a|aa)+ इंजन को हर अतिरिक्त कैरेक्टर मिलाने के दो तरीके देता है, प्रति कैरेक्टर खोज-वृक्ष दोगुना करता है।
- संरचनात्मक सुधारसुधार संरचनात्मक हैं: भीतरी मैच को असंदिग्ध बनाएँ, स्पष्ट लंबाई सीमाओं से बाँधें, और हमेशा लगभग-मैच इनपुट टेस्ट करें, सिर्फ़ मान्य वाले नहीं।
मैच पर भरोसा करने से पहले एंकर लगाएँ
सबस्ट्रिंग खोजने वाला पैटर्न वैल्यू सत्यापित करने वाला पैटर्न नहीं है। /\d+/ abc123xyz के अंदर मिलता है; /^\d+$/ सिर्फ़ अंक स्वीकार करता है। ज़्यादातर वैलिडेशन बग गायब एंकर होते हैं, और ज़्यादातर एक्सट्रैक्शन बग ऐसे एंकर जो वहाँ नहीं होने चाहिए।
- शुरू और अंत^ और $ मैच को स्ट्रिंग के शुरू और अंत में ठीक करते हैं — या मल्टीलाइन फ़्लैग चालू होने पर हर लाइन के, जो “पूरे इनपुट” का अर्थ चुपचाप बदल देता है।
- शब्द सीमाएँ\b शब्द सीमाएँ छोटे पैटर्न को लंबे शब्दों के अंदर मिलने से रोकती हैं: \bcat\b जानवर मिलाता है, concatenate के अंदर का cat नहीं।
- खोज बनाम वैलिडेशनपहले ही तय करें कि खोज है या वैलिडेशन: एक्सट्रैक्शन पैटर्न आमतौर पर बिना एंकर चाहते हैं, वैलिडेटर लगभग हमेशा दोनों।
यथार्थ सैंपल डेटा से टेस्ट करें
तीन सुस्वच्छ उदाहरणों पर सिद्ध पैटर्न प्रोडक्शन में चौथे असली पर विफल होता है। ऐसा सैंपल सेट बनाएँ जो इनपुट वितरण को प्रतिबिंबित करे: सबसे लंबी वैध वैल्यू, खाली स्ट्रिंग, व्हाइटस्पेस रूप, Unicode नाम, और वह लगभग-मैच जो लगभग मिले पर मिलना नहीं चाहिए।
- लगभग-मैचलगभग-मैच शामिल करें: ईमेल पैटर्न को a@b और a b@c.d के सामने टेस्ट करना चाहिए, सिर्फ़ सुगठित पतों के सामने नहीं।
- Unicodeउच्चारण चिह्न वाले नाम और अन्य Unicode डेटा जाँचें: u के साथ डॉट Unicode code point लेता है, लेकिन \w सभी Unicode अक्षरों की वर्ग-श्रेणी नहीं है। ज़रूरत पर \p{L} जैसी property escape इस्तेमाल करें।
- पूरा सेट फिर चलाएँसैंपल सेट पैटर्न के पास रखें; पैटर्न बदलने पर पूरा सेट फिर चलाएँ, सिर्फ़ वह केस नहीं जिसने बदलाव को प्रेरित किया।
फ़्लैग सिर्फ़ खोज नहीं, भाषा बदलते हैं
फ़्लैग पैटर्न के अर्थ का हिस्सा हैं। g तय करता है कि पहला मैच मिले या सारे, i केस समेटता है, m के ^ और $ को लाइनों पर फिर एंकर करता है, s डॉट को न्यूलाइन पार करने देता है, और u इंजन को Unicode-सचेत मोड में सख्त सिंटैक्स के साथ बदल देता है।
वर्कस्पेस पैटर्न को आपके चुने फ़्लैग के साथ मूल्यांकित करता है और हर मैच को उसके शुरू और अंत ऑफ़सेट के साथ, क्रमांकित और नामित कैप्चर ग्रुप को उनकी अपनी स्थितियों के साथ, और लाइव रिप्लेसमेंट प्रीव्यू के साथ सूचीबद्ध करता है — ताकि फ़्लैग बदलाव सिद्धांत नहीं, परिणाम में ठोस अंतर के रूप में दिखे।
- g और lastIndexg के बिना test() और match() सिर्फ़ पहला हिट देखते हैं; g के साथ रेगेक्स ऑब्जेक्ट lastIndex स्थिति रखता है जो बार-बार test() कॉल के परिणाम बदल-बदल देती है — एक कुख्यात प्रोडक्शन बग।
- s डॉट चौड़ा करता हैs (dotAll) डॉट को न्यूलाइन मिलाने देता है, जो ग्लोबल रूप से चालू होने पर पुराने पैटर्न की भूख चुपचाप बढ़ा सकता है।
- u और साथीu Unicode-aware escape और सख़्त सिंटैक्स देता है; वह \w या \d को सभी Unicode अक्षर या अंकों की सामान्य श्रेणी नहीं बनाता। टेस्टर d, y और v भी संभालता है।
पैटर्न और सैंपल लोकल रखें
टेस्ट डेटा अक्सर असली डेटा होता है: ग्राहक ईमेल, आंतरिक लॉग लाइनें, घटना रिपोर्ट के आइडेंटिफ़ायर। उसे होस्ट किए टेस्टर में पेस्ट करना मतलब उसे किसी और के इंफ्रास्ट्रक्चर पर भेजना। ब्राउज़र-आधारित टेस्टर सत्र को टैब में रखता है — पैटर्न और सैंपल टेक्स्ट आपके अपने डिवाइस के इंजन से मूल्यांकित होते हैं और कभी ट्रांसमिट नहीं होते।
लोकल रनटाइम अपनी छतों के बारे में स्पष्ट है: 4,096 कैरेक्टर तक के पैटर्न, 100,000 कैरेक्टर तक का सैंपल टेक्स्ट, 20,000 तक के रिप्लेसमेंट, और प्रति रन अधिकतम 1,000 रिपोर्ट किए मैच। ये सीमाएँ डेवलपमेंट और डीबगिंग के लिए आकारी गई हैं; बल्क लॉग विश्लेषण लोकल स्क्रिप्ट में होना चाहिए, ब्राउज़र टैब में नहीं।
सिर्फ़ वही कॉपी करें जो चाहिए — तैयार पैटर्न और रिप्लेसमेंट स्ट्रिंग — और सैंपल डेटा वहीं छोड़ें जहाँ से शुरू हुआ: आपकी मशीन पर।
पैटर्न स्थानीय रूप से टेस्ट करेंनिकाला गया डेटा आमतौर पर JSON में उतरता है।
जब पैटर्न कच्चे टेक्स्ट से वैल्यू निकाल ले, तो बने पेलोड को डिटरमिनिस्टिक लोकल दिनचर्या से इंस्पेक्ट और डिफ़ करें।