रेगुलर एक्सप्रेशन की आने वाली सुविधाएं

ES2015 में, JavaScript भाषा में कई नई सुविधाएं जोड़ी गई हैं. इनमें यूनिकोड (/u) और स्टिक (/y) फ़्लैग के साथ रेगुलर एक्सप्रेशन सिंटैक्स में काफ़ी सुधार शामिल हैं. हालांकि, इसके बाद भी इस पर काम जारी है. V8 टीम ने TC39 (ECMAScript स्टैंडर्ड बॉडी) के अन्य सदस्यों के साथ मिलकर, रेगुलर एक्सप्रेशन को और भी बेहतर बनाने के लिए कई नई सुविधाओं का प्रस्ताव दिया है और उन्हें डिज़ाइन किया है.

फ़िलहाल, इन सुविधाओं को JavaScript के स्पेसिफ़िकेशन में शामिल करने का प्रस्ताव दिया जा रहा है. इन प्रस्तावों को पूरी तरह से स्वीकार नहीं किया गया है, लेकिन ये TC39 प्रोसेस के तीसरे चरण में पहुंच चुके हैं. हमने इन सुविधाओं को फ़्लैग के तौर पर लागू किया है (नीचे देखें). इससे, हम स्पेसिफ़िकेशन को फ़ाइनल करने से पहले, प्रस्ताव के लेखकों को डिज़ाइन और लागू करने के बारे में समय पर सुझाव दे पाएंगे.

इस ब्लॉग पोस्ट में, आपको इस रोमांचक भविष्य की झलक मिलेगी. अगर आपको आने वाले समय में दिए जाने वाले उदाहरणों के साथ-साथ, JavaScript की प्रयोग के तौर पर उपलब्ध सुविधाओं का इस्तेमाल करना है, तो chrome://flags/#enable-javascript-harmony पर जाकर उन्हें चालू करें.

नाम वाले कैप्चर

रेगुलर एक्सप्रेशन में कैप्चर (या ग्रुप) हो सकते हैं, जो मैच किए गए टेक्स्ट के किसी हिस्से को कैप्चर कर सकते हैं. अब तक, डेवलपर इन कैप्चर को सिर्फ़ उनके इंडेक्स के हिसाब से रेफ़र कर सकते थे. यह इंडेक्स, पैटर्न में कैप्चर की पोज़िशन से तय होता है.

const pattern = /(\d{4})-(\d{2})-(\d{2})/u;
const result = pattern.exec('2017-07-10');
// result[0] === '2017-07-10'
// result[1] === '2017'
// result[2] === '07'
// result[3] === '10'

हालांकि, रेगुलर एक्सप्रेशन को पढ़ना, लिखना, और मैनेज करना पहले से ही मुश्किल है. साथ ही, अंकों के रेफ़रंस से समस्याएं और बढ़ सकती हैं. उदाहरण के लिए, लंबे पैटर्न में किसी खास कैप्चर का इंडेक्स तय करना मुश्किल हो सकता है:

/(?:(.)(.(?<=[^(])(.)))/  // Index of the last capture?

इससे भी बुरा यह है कि पैटर्न में बदलाव करने से, सभी मौजूदा कैप्चर के इंडेक्स में बदलाव हो सकता है:

/(a)(b)(c)\3\2\1/     // A few simple numbered backreferences.
/(.)(a)(b)(c)\4\3\2/  // All need to be updated.

नाम वाले कैप्चर, आने वाली एक सुविधा है. इससे डेवलपर, कैप्चर को नाम असाइन कर सकते हैं. इससे इन समस्याओं को कम करने में मदद मिलती है. इसका सिंटैक्स, Perl, Java, .Net, और Ruby जैसा ही है:

const pattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
const result = pattern.exec('2017-07-10');
// result.groups.year === '2017'
// result.groups.month === '07'
// result.groups.day === '10'

नेम कैप्चर का रेफ़रंस, नेम बैकरेफ़रंस और String.prototype.replace के ज़रिए भी दिया जा सकता है:

// Named backreferences.
/(?<LowerCaseX>x)y\k<LowerCaseX>/.test('xyx');  // true

// String replacement.
const pattern = /(?<fst>a)(?<snd>b)/;
'ab'.replace(pattern, '$<snd>$<fst>');                              // 'ba'
'ab'.replace(pattern, (m, p1, p2, o, s, {fst, snd}) => fst + snd);  // 'ba'

इस नई सुविधा की पूरी जानकारी, स्पेसिफ़िकेशन के प्रस्ताव में उपलब्ध है.

dotAll फ़्लैग

डिफ़ॉल्ट रूप से, रेगुलर एक्सप्रेशन में . एटम, लाइन के आखिर में मौजूद वर्णों को छोड़कर, किसी भी वर्ण से मैच करता है:

/foo.bar/u.test('foo\nbar');   // false

एक प्रस्ताव में dotAll मोड को शामिल किया गया है. इसे /s फ़्लैग की मदद से चालू किया जा सकता है. dotAll मोड में, . लाइन के आखिर में मौजूद वर्ण से भी मैच करता है.

/foo.bar/su.test('foo\nbar');  // true

इस नई सुविधा की पूरी जानकारी, स्पेसिफ़िकेशन के प्रस्ताव में उपलब्ध है.

यूनिकोड प्रॉपर्टी के लिए एस्केप

ES2015 में यूनिकोड के बारे में जानकारी देने की सुविधा के साथ, ऐसे कई वर्ण हैं जिन्हें संख्या माना जा सकता है. उदाहरण के लिए, सर्कल में अंक एक: ① या शब्द के वर्ण, जैसे कि बर्फ़ के लिए चाइनीज़ वर्ण: 雪.

इनमें से किसी भी आइटम का मिलान \d या \w से नहीं किया जा सकता. इन शॉर्टहैंड के मतलब में बदलाव करने से, रेगुलर एक्सप्रेशन के मौजूदा पैटर्न काम नहीं करेंगे.

इसके बजाय, प्रॉपर्टी के लिए नए एस्केप सीक्वेंस पेश किए जा रहे हैं. ध्यान दें कि ये सिर्फ़ यूनिकोड के बारे में जानकारी रखने वाले रेगुलर एक्सप्रेशन के लिए उपलब्ध हैं. इन एक्सप्रेशन को /u फ़्लैग से दिखाया जाता है.

/\p{Number}/u.test('①');      // true
/\p{Alphabetic}/u.test('雪');  // true

इनवर्स का मिलान \P से किया जा सकता है.

/\P{Number}/u.test('①');      // false
/\P{Alphabetic}/u.test('雪');  // false

यूनिकोड कंसोर्टियम कई और प्रॉपर्टी तय करता है. उदाहरण के लिए, गणित के सिंबल या जैपनीज़ हीरागाना वर्णों के लिए:

/^\p{Math}+$/u.test('∛∞∉');                            // true
/^\p{Script_Extensions=Hiragana}+$/u.test('ひらがな');  // true

इस्तेमाल की जा सकने वाली यूनिकोड प्रॉपर्टी क्लास की पूरी सूची, मौजूदा स्पेसिफ़िकेशन के प्रस्ताव में देखी जा सकती है. ज़्यादा उदाहरणों के लिए, जानकारी देने वाला यह लेख पढ़ें.

लुकबैक एश्योरेशन

लुकअहेड एश्योरमेंट, शुरू से ही JavaScript के रेगुलर एक्सप्रेशन सिंटैक्स का हिस्सा रहे हैं. आखिरकार, इनके साथ काम करने वाले, लुकबैक एश्योरेशन को पेश किया जा रहा है. आपमें से कुछ लोगों को याद होगा कि यह सुविधा, V8 में पहले से ही मौजूद है. हम ES2015 में बताए गए यूनिकोड फ़्लैग को लागू करने के लिए, बैकवर्ड लुकऐसेर्ट का भी इस्तेमाल करते हैं.

नाम से पहले से ही उसके मतलब के बारे में काफ़ी अच्छी तरह पता चलता है. इसकी मदद से, किसी पैटर्न को सिर्फ़ तब मैच करने की पाबंदी लगाई जा सकती है, जब उसके पहले लुकबैक ग्रुप में मौजूद पैटर्न हो. यह एट्रिब्यूट, मैच करने वाले और मैच न करने वाले, दोनों फ़्लेवर में उपलब्ध है:

/(?<=\$)\d+/.exec('$1 is worth about ¥123');  // ['1']
/(?<!\$)\d+/.exec('$1 is worth about ¥123');  // ['123']

ज़्यादा जानकारी के लिए, lookbehind वाले दावों के बारे में बताने वाली हमारी पिछली ब्लॉग पोस्ट और उससे जुड़े V8 टेस्ट केस के उदाहरण देखें.

आभार

इस ब्लॉग पोस्ट में उन लोगों का जिक्र करना ज़रूरी है जिन्होंने इसे पूरा करने के लिए कड़ी मेहनत की है. इनमें खास तौर पर, भाषा के चैंपियन मैथियास बीन्स, डैन एहरनबर्ग, क्लाउड पाचे, ब्रायन टर्ल्सन, थॉमस वुड, गोर्कम याकिन, और Irregexp गुरु एरिक कोरी शामिल हैं. साथ ही, उन सभी लोगों का भी जिक्र करना ज़रूरी है जिन्होंने भाषा के स्पेसिफ़िकेशन और V8 में इन सुविधाओं को लागू करने में योगदान दिया है.

हमें उम्मीद है कि आपको रेगुलर एक्सप्रेशन की इन नई सुविधाओं को लेकर उतना ही उत्साह होगा जितना हमें है!