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

जैकब ग्रुबर
यांग गुओ

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

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

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

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

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

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 mode में, . लाइन टर्मिनेटर से भी मैच करता है.

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

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

यूनिकोड प्रॉपर्टी एस्केप हो जाती है

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

इनमें से किसी का भी मिलान \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']

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

स्वीकार हैं

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

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