जावास्क्रिप्ट में एक लंबी नियमित अभिव्यक्ति को कई लाइनों में कैसे विभाजित किया जाए?


138

मेरी एक बहुत लंबी नियमित अभिव्यक्ति है, जिसे मैं JSL नियमों के अनुसार प्रत्येक लाइन लंबाई 80 वर्ण रखने के लिए अपने जावास्क्रिप्ट कोड में कई लाइनों में विभाजित करना चाहता हूं। यह सिर्फ पढ़ने के लिए बेहतर है, मुझे लगता है। यहाँ पैटर्न नमूना है:

var pattern = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

4
ऐसा लगता है कि आप ई-मेल पते को मान्य करने का प्रयास कर रहे हैं। बस क्यों नहीं करते /\S+@\S+\.\S+/?
बार्ट कीर्स सेप

1
आपको शायद ऐसा करने के लिए एक नियमित अभिव्यक्ति के बिना, या कई छोटे नियमित अभिव्यक्तियों के साथ एक तरीका खोजना चाहिए। यह लंबे समय तक एक नियमित अभिव्यक्ति की तुलना में बहुत अधिक पठनीय होगा। यदि आपकी नियमित अभिव्यक्ति लगभग 20 से अधिक वर्णों की है, तो संभवतः ऐसा करने का एक बेहतर तरीका है।
फोर्ब्स लिंडसे

2
क्या 80 अक्षर व्यापक के साथ आजकल अप्रचलित नहीं हैं?
ओलेग वी। वोल्कोव

7
@ ओलेगवी.विल्कोव नं। एक व्यक्ति एक कमरे में एक आभासी टर्मिनल, विम में विभाजित खिड़कियों का उपयोग कर सकता है। यह मान लेना गलत है कि हर कोई आपके जैसे ही व्यूपोर्ट में कोडिंग करेगा। इसके अलावा, अपनी लाइनों को 80 वर्णों तक सीमित करने से आप अपने कोड को छोटे कार्यों में तोड़ सकते हैं।
सिन्टिक

खैर, मैं निश्चित रूप से यहाँ ऐसा करने के लिए आपकी प्रेरणा देख रहा हूँ - एक बार जब यह रेगेक्स कई लाइनों में विभाजित हो जाता है, जैसा कि कूलिल्क द्वारा प्रदर्शित किया गया है, तो यह तुरंत पठनीय, स्व-दस्तावेजीकरण कोड का एक आदर्श उदाहरण बन जाता है। ¬_
मार्क अमेरी

जवाबों:


115

आप इसे एक स्ट्रिंग में बदल सकते हैं और कॉल करके अभिव्यक्ति बना सकते हैं new RegExp():

var myRE = new RegExp (['^(([^<>()[\]\\.,;:\\s@\"]+(\\.[^<>(),[\]\\.,;:\\s@\"]+)*)',
                        '|(\\".+\\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.',
                        '[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\\.)+',
                        '[a-zA-Z]{2,}))$'].join(''));

टिप्पणियाँ:

  1. जब एक स्ट्रिंग को अभिव्यक्ति शाब्दिक रूप से परिवर्तित करना है तो आपको सभी बैकस्लैश से बचना होगा क्योंकि स्ट्रिंग शाब्दिक का मूल्यांकन करते समय बैकस्लैश का सेवन किया जाता है । (अधिक विस्तार के लिए कायो की टिप्पणी देखें।)
  2. RegExp एक दूसरे पैरामीटर के रूप में संशोधक को स्वीकार करता है

    /regex/g => new RegExp('regex', 'g')

[ अतिरिक्त ES20xx (टैग किए गए टेम्पलेट)]

ES20xx में आप टैग किए गए टेम्प्लेट का उपयोग कर सकते हैं । स्निपेट देखें।

ध्यान दें:

  • यहाँ नुकसान यह है कि आप नियमित अभिव्यक्ति स्ट्रिंग में सादे खाली स्थान के उपयोग नहीं कर सकते (हमेशा इस्तेमाल करते हैं \s, \s+, \s{1,x}, \t, \nआदि)।

(() => {
  const createRegExp = (str, opts) => 
    new RegExp(str.raw[0].replace(/\s/gm, ""), opts || "");
  const yourRE = createRegExp`
    ^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|
    (\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|
    (([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$`;
  console.log(yourRE);
  const anotherLongRE = createRegExp`
    (\byyyy\b)|(\bm\b)|(\bd\b)|(\bh\b)|(\bmi\b)|(\bs\b)|(\bms\b)|
    (\bwd\b)|(\bmm\b)|(\bdd\b)|(\bhh\b)|(\bMI\b)|(\bS\b)|(\bMS\b)|
    (\bM\b)|(\bMM\b)|(\bdow\b)|(\bDOW\b)
    ${"gi"}`;
  console.log(anotherLongRE);
})();


4
एक new RegExpबहु नियमित अभिव्यक्ति के लिए एक शानदार तरीका है। सरणियों में शामिल होने के बजाय, आप बस एक स्ट्रिंग var reg = new RegExp('^([a-' + 'z]+)$','i');
संघनन

43
सावधानी: उपरोक्त उत्तर का उपयोग करके एक लंबी नियमित अभिव्यक्ति शाब्दिक को कई लाइनों में तोड़ा जा सकता है। हालाँकि इसे देखभाल की आवश्यकता है क्योंकि आप नियमित अभिव्यक्ति शाब्दिक (साथ परिभाषित //) को कॉपी नहीं कर सकते हैं और इसे RegExp कंस्ट्रक्टर के स्ट्रिंग तर्क के रूप में पेस्ट कर सकते हैं। इसका कारण यह है कि स्ट्रिंग शाब्दिक का मूल्यांकन करते समय बैकस्लैश अक्षर भस्म हो जाते हैं । उदाहरण: /Hey\sthere/द्वारा प्रतिस्थापित नहीं किया जा सकता है new RegExp("Hey\sthere")। इसके बजाय इसे new RegExp("Hey\\sthere")नोट के अतिरिक्त बैकस्लैश द्वारा प्रतिस्थापित किया जाना चाहिए ! इसलिए मैं एक लंबी लाइन पर एक लंबे रेगेक्स शाब्दिक को छोड़ना पसंद करता हूं
कायो

5
ऐसा करने का एक स्पष्ट तरीका यह भी है कि नामित उप-नाम सार्थक उपखंड बनाए जाएं, और उन्हें तार के रूप में या एक सरणी में जोड़ा जाए। यह आपको RegExpएक तरह से निर्माण करने देता है जो समझने में बहुत आसान है।
क्रिस क्रिचो

117

@KooiInc उत्तर का विस्तार करते हुए, आप ऑब्जेक्ट की sourceसंपत्ति का उपयोग करके प्रत्येक विशेष वर्ण से बचने से मैन्युअल रूप से बच सकते हैं RegExp

उदाहरण:

var urlRegex= new RegExp(''
  + /(?:(?:(https?|ftp):)?\/\/)/.source     // protocol
  + /(?:([^:\n\r]+):([^@\n\r]+)@)?/.source  // user:pass
  + /(?:(?:www\.)?([^\/\n\r]+))/.source     // domain
  + /(\/[^?\n\r]+)?/.source                 // request
  + /(\?[^#\n\r]*)?/.source                 // query
  + /(#?[^\n\r]*)?/.source                  // anchor
);

या यदि आप उस .sourceसंपत्ति को दोहराने से बचना चाहते हैं जो आप Array.map()फ़ंक्शन का उपयोग करके कर सकते हैं :

var urlRegex= new RegExp([
  /(?:(?:(https?|ftp):)?\/\/)/      // protocol
  ,/(?:([^:\n\r]+):([^@\n\r]+)@)?/  // user:pass
  ,/(?:(?:www\.)?([^\/\n\r]+))/     // domain
  ,/(\/[^?\n\r]+)?/                 // request
  ,/(\?[^#\n\r]*)?/                 // query
  ,/(#?[^\n\r]*)?/                  // anchor
].map(function(r) {return r.source}).join(''));

ES6 में मानचित्र फ़ंक्शन को निम्न तक घटाया जा सकता है: .map(r => r.source)


3
बिल्कुल मैं जो देख रहा था, वह सुपर-क्लीन था। धन्यवाद!
मरिअन ज़गोरुइको

10
यह लंबे रेगेक्स में टिप्पणी जोड़ने के लिए वास्तव में सुविधाजनक है। हालाँकि, यह समान पंक्ति में लघुकोष्ठक होने से सीमित है।
नाथन एस। वाटसन-हाई

निश्चित रूप से, यह! प्रत्येक उप-रेगेक्स टिप्पणी करने की क्षमता के साथ सुपर अच्छा है।
गैरीओ

धन्यवाद, इसने रेगेक्स फंक्शन में स्रोत डालने में मदद की
कोड

बहुत चालाक। धन्यवाद, इस विचार से मुझे बहुत मदद मिली। बनाने के लिए मैं एक समारोह में पूरी बात समझाया तो यह और भी क्लीनर:: बस एक पक्ष नोट के रूप में combineRegex = (...regex) => new RegExp(regex.map(r => r.source).join("")): उपयोगcombineRegex(/regex1/, /regex2/, ...)
Scindix

25

में तार का उपयोग करना new RegExpअजीब है क्योंकि आपको सभी बैकस्लैश से बचना चाहिए। आप छोटे regexes लिख सकते हैं और उन्हें संक्षिप्त कर सकते हैं।

आइए इस रेगेक्स को विभाजित करें

/^foo(.*)\bar$/

हम बाद में चीजों को और अधिक सुंदर बनाने के लिए एक फ़ंक्शन का उपयोग करेंगे

function multilineRegExp(regs, options) {
    return new RegExp(regs.map(
        function(reg){ return reg.source; }
    ).join(''), options);
}

और अब रॉक करते हैं

var r = multilineRegExp([
     /^foo/,  // we can add comments too
     /(.*)/,
     /\bar$/
]);

चूंकि इसकी एक लागत है, वास्तविक रेगेक्स को सिर्फ एक बार बनाने की कोशिश करें और फिर उसका उपयोग करें।


यह बहुत अच्छा है - न केवल आपको अतिरिक्त भागने की ज़रूरत नहीं है, बल्कि आप उप-रेक्सक्स के लिए विशेष सिंटैक्स हाइलाइट भी रखते हैं!
क्वांज़क

हालांकि, आपको यह सुनिश्चित करने की आवश्यकता है कि आपके उप-रेक्सक्स स्वयं-निहित हैं, या प्रत्येक को एक नए ब्रैकेट समूह में लपेटते हैं। उदाहरण: multilineRegExp([/a|b/, /c|d])परिणाम में /a|bc|d/, जबकि आपका मतलब था (a|b)(c|d)
क्विजक

6

यहाँ अच्छे उत्तर हैं, लेकिन पूर्णता के लिए किसी को प्रोटोटाइप श्रृंखला के साथ जावास्क्रिप्ट की मूल विशेषता का उल्लेख करना चाहिए । इस तरह कुछ इस विचार को दिखाता है:

RegExp.prototype.append = function(re) {
  return new RegExp(this.source + re.source, this.flags);
};

let regex = /[a-z]/g
.append(/[A-Z]/)
.append(/[0-9]/);

console.log(regex); //=> /[a-z][A-Z][0-9]/g


यह यहां सबसे अच्छा जवाब है।
parttimeturtle

6

टेम्पलेट शाब्दिक की अद्भुत दुनिया के लिए धन्यवाद , अब आप ईएस 6 में बड़े, मल्टी-लाइन, अच्छी तरह से टिप्पणी की जा सकती हैं, और यहां तक ​​कि शब्दार्थ नेगेस भी लिख सकते हैं ।

//build regexes without worrying about
// - double-backslashing
// - adding whitespace for readability
// - adding in comments
let clean = (piece) => (piece
    .replace(/((^|\n)(?:[^\/\\]|\/[^*\/]|\\.)*?)\s*\/\*(?:[^*]|\*[^\/])*(\*\/|)/g, '$1')
    .replace(/((^|\n)(?:[^\/\\]|\/[^\/]|\\.)*?)\s*\/\/[^\n]*/g, '$1')
    .replace(/\n\s*/g, '')
);
window.regex = ({raw}, ...interpolations) => (
    new RegExp(interpolations.reduce(
        (regex, insert, index) => (regex + insert + clean(raw[index + 1])),
        clean(raw[0])
    ))
);

इसका उपयोग करके अब आप इस तरह से रेगीज़ लिख सकते हैं:

let re = regex`I'm a special regex{3} //with a comment!`;

आउटपुट

/I'm a special regex{3}/

या बहुस्तरीय के बारे में क्या?

'123hello'
    .match(regex`
        //so this is a regex

        //here I am matching some numbers
        (\d+)

        //Oh! See how I didn't need to double backslash that \d?
        ([a-z]{1,3}) /*note to self, this is group #2*/
    `)
    [2]

आउटपुट hel, साफ!
"क्या होगा अगर मुझे वास्तव में एक नई खोज करने की आवश्यकता है?", ठीक है फिर \nमूर्खतापूर्ण उपयोग करें !
मेरे फ़ायरफ़ॉक्स और क्रोम पर काम करना।


ठीक है, "कैसे कुछ और अधिक जटिल के बारे में?"
यकीन है, यहाँ जेएस पार्सर मैं नष्ट कर रहा था एक वस्तु का एक टुकड़ा पर काम कर रहा था :

regex`^\s*
    (
        //closing the object
        (\})|

        //starting from open or comma you can...
        (?:[,{]\s*)(?:
            //have a rest operator
            (\.\.\.)
            |
            //have a property key
            (
                //a non-negative integer
                \b\d+\b
                |
                //any unencapsulated string of the following
                \b[A-Za-z$_][\w$]*\b
                |
                //a quoted string
                //this is #5!
                ("|')(?:
                    //that contains any non-escape, non-quote character
                    (?!\5|\\).
                    |
                    //or any escape sequence
                    (?:\\.)
                //finished by the quote
                )*\5
            )
            //after a property key, we can go inside
            \s*(:|)
      |
      \s*(?={)
        )
    )
    ((?:
        //after closing we expect either
        // - the parent's comma/close,
        // - or the end of the string
        \s*(?:[,}\]=]|$)
        |
        //after the rest operator we expect the close
        \s*\}
        |
        //after diving into a key we expect that object to open
        \s*[{[:]
        |
        //otherwise we saw only a key, we now expect a comma or close
        \s*[,}{]
    ).*)
$`

यह आउटपुट करता है /^\s*((\})|(?:[,{]\s*)(?:(\.\.\.)|(\b\d+\b|\b[A-Za-z$_][\w$]*\b|("|')(?:(?!\5|\\).|(?:\\.))*\5)\s*(:|)|\s*(?={)))((?:\s*(?:[,}\]=]|$)|\s*\}|\s*[{[:]|\s*[,}{]).*)$/

और इसे थोड़ा डेमो के साथ चल रहा है?

let input = '{why, hello, there, "you   huge \\"", 17, {big,smelly}}';
for (
    let parsed;
    parsed = input.match(r);
    input = parsed[parsed.length - 1]
) console.log(parsed[1]);

सफलतापूर्वक आउटपुट

{why
, hello
, there
, "you   huge \""
, 17
,
{big
,smelly
}
}

उद्धृत स्ट्रिंग के सफल कैप्चरिंग पर ध्यान दें।
मैंने इसे क्रोम और फ़ायरफ़ॉक्स पर परीक्षण किया, एक इलाज का काम करता है!

यदि आप उत्सुक हैं कि मैं क्या कर रहा था , और इसका प्रदर्शन देख सकते हैं
हालांकि यह केवल क्रोम पर काम करता है, क्योंकि फ़ायरफ़ॉक्स बैकरेफेरेंस या नामित समूहों का समर्थन नहीं करता है। तो ध्यान दें कि इस उत्तर में दिए गए उदाहरण वास्तव में एक न्युरेटेड संस्करण है और अवैध तारों को स्वीकार करने में आसानी से धोखा हो सकता है।


1
आपको इसे NodeJS पैकेज के रूप में निर्यात करने के बारे में सोचना चाहिए, यह अद्भुत है
rmobis

1
हालांकि मैंने इसे खुद कभी नहीं किया है, यहां बहुत अच्छी तरह से ट्यूटोरियल है: zellwk.com/blog/publish-to-npm । मैं पृष्ठ के अंत में np चेक करने का सुझाव दूंगा। मैंने कभी इसका उपयोग नहीं किया है, लेकिन सिंद्रे सोरहूस इन चीजों के साथ एक जादूगर है, इसलिए मैं इसे पास नहीं करूंगा।
rmobis

4

ऊपर रेगेक्स कुछ काले स्लैश को याद कर रहा है जो ठीक से काम नहीं कर रहा है इसलिए, मैंने रेगेक्स को संपादित किया। कृपया इस रेगेक्स पर विचार करें जो ईमेल सत्यापन के लिए 99.99% काम करता है।

let EMAIL_REGEXP = 
new RegExp (['^(([^<>()[\\]\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\.,;:\\s@\"]+)*)',
                    '|(".+"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.',
                    '[0-9]{1,3}\])|(([a-zA-Z\\-0-9]+\\.)+',
                    '[a-zA-Z]{2,}))$'].join(''));

1

सरणी से बचने के लिए join, आप निम्न सिंटैक्स का उपयोग कर सकते हैं:

var pattern = new RegExp('^(([^<>()[\]\\.,;:\s@\"]+' +
  '(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@' +
  '((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|' +
  '(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$');

0

व्यक्तिगत रूप से, मैं कम जटिल रीगेक्स के लिए जाऊंगा:

/\S+@\S+\.\S+/

ज़रूर, यह आपके मौजूदा पैटर्न से कम सटीक है, लेकिन आप क्या हासिल करने की कोशिश कर रहे हैं? क्या आप उन आकस्मिक त्रुटियों को पकड़ने की कोशिश कर रहे हैं जो आपके उपयोगकर्ता दर्ज कर सकते हैं, या क्या आप चिंतित हैं कि आपके उपयोगकर्ता अमान्य पते दर्ज करने का प्रयास कर सकते हैं? यदि यह पहला है, तो मैं एक आसान पैटर्न के लिए जाऊँगा। यदि यह बाद का है, तो उस पते पर भेजे गए ई-मेल का जवाब देकर कुछ सत्यापन एक बेहतर विकल्प हो सकता है।

हालाँकि, यदि आप अपने वर्तमान पैटर्न का उपयोग करना चाहते हैं, तो यह इस तरह से छोटे उप-पैटर्न से निर्माण करके पढ़ना (और बनाए रखना) आसान होगा (IMO):

var box1 = "([^<>()[\]\\\\.,;:\s@\"]+(\\.[^<>()[\\]\\\\.,;:\s@\"]+)*)";
var box2 = "(\".+\")";

var host1 = "(\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])";
var host2 = "(([a-zA-Z\-0-9]+\\.)+[a-zA-Z]{2,})";

var regex = new RegExp("^(" + box1 + "|" + box2 + ")@(" + host1 + "|" + host2 + ")$");

21
डाउनवोटिंग - हालांकि रेगेक्स जटिलता को कम करने के बारे में आपकी टिप्पणियां वैध हैं, ओपी विशेष रूप से पूछ रहा है कि "कई लाइनों पर लंबे रेगेक्स को कैसे विभाजित करें"। इसलिए यद्यपि आपकी सलाह मान्य है, यह गलत कारणों के लिए दी गई है। उदाहरण के लिए प्रोग्रामिंग भाषा के आसपास काम करने के लिए व्यावसायिक तर्क बदलना। इसके अलावा, आपके द्वारा दिया गया कोड उदाहरण काफी बदसूरत है।
sleepycal

4
@sleepycal मुझे लगता है कि बार्ट ने सवाल का जवाब दिया है। उसके उत्तर का अंतिम भाग देखें। उन्होंने सवाल का जवाब दिया है और साथ ही एक विकल्प भी दिया है।
निधिन डेविड

0

आप बस स्ट्रिंग ऑपरेशन का उपयोग कर सकते हैं।

var pattenString = "^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|"+
"(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|"+
"(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$";
var patten = new RegExp(pattenString);

0

मैंने सब कुछ एनकैप्सुलेट करके और समूहों और चरित्र सेटों को विभाजित करने के लिए समर्थन को लागू करके कोरुन के उत्तर को बेहतर बनाने की कोशिश की - इस विधि को और अधिक बहुमुखी बना दिया।

इस स्निपेट का उपयोग करने के लिए आपको वैरेडिक फ़ंक्शन को कॉल करने की आवश्यकता है combineRegexजिनके तर्क नियमित अभिव्यक्ति ऑब्जेक्ट हैं जिन्हें आपको संयोजित करने की आवश्यकता है। इसका कार्यान्वयन नीचे पाया जा सकता है।

कैप्चरिंग समूहों को सीधे उस तरह से विभाजित नहीं किया जा सकता है, क्योंकि यह सिर्फ एक कोष्ठक के साथ कुछ हिस्सों को छोड़ देगा। आपका ब्राउज़र अपवाद के साथ विफल हो जाएगा।

इसके बजाय मैं बस एक सरणी के अंदर कैप्चर समूह की सामग्री पास कर रहा हूं। कोष्ठक स्वचालित रूप से जोड़े जाते हैं जब combineRegexएक सरणी का सामना करते हैं।

इसके अलावा क्वांटिफायर को कुछ का पालन करने की आवश्यकता है। यदि किसी कारण से नियमित अभिव्यक्ति को एक मात्रा के सामने विभाजित करने की आवश्यकता होती है, तो आपको एक जोड़ी कोष्ठक जोड़ना होगा। ये अपने आप हट जाएंगे। मुद्दा यह है कि एक खाली कब्जा समूह बहुत बेकार है और इस तरह से क्वांटिफायर के पास कुछ करने के लिए है। गैर-कैप्चरिंग समूहों ( /(?:abc)/हो जाता है [/()?:abc/]) जैसी चीजों के लिए एक ही विधि का उपयोग किया जा सकता है ।

यह एक सरल उदाहरण का उपयोग करके समझाया गया है:

var regex = /abcd(efghi)+jkl/;

बन जाएगा:

var regex = combineRegex(
    /ab/,
    /cd/,
    [
        /ef/,
        /ghi/
    ],
    /()+jkl/    // Note the added '()' in front of '+'
);

यदि आपको वर्ण सेट को विभाजित करना चाहिए तो आप {"":[regex1, regex2, ...]}सरणियों ( [regex1, regex2, ...]) के बजाय ऑब्जेक्ट ( ) का उपयोग कर सकते हैं । कुंजी की सामग्री कुछ भी हो सकती है जब तक कि ऑब्जेक्ट में केवल एक कुंजी होती है। ध्यान दें कि आपके बजाय डमी शुरुआत के रूप में ()उपयोग करना होगा ]यदि पहले चरित्र को क्वांटिफायर के रूप में व्याख्या किया जा सकता है। Ie /[+?]/बन जाता है{"":[/]+?/]}

यहाँ स्निपेट और अधिक पूर्ण उदाहरण है:

function combineRegexStr(dummy, ...regex)
{
    return regex.map(r => {
        if(Array.isArray(r))
            return "("+combineRegexStr(dummy, ...r).replace(dummy, "")+")";
        else if(Object.getPrototypeOf(r) === Object.getPrototypeOf({}))
            return "["+combineRegexStr(/^\]/, ...(Object.entries(r)[0][1]))+"]";
        else 
            return r.source.replace(dummy, "");
    }).join("");
}
function combineRegex(...regex)
{
    return new RegExp(combineRegexStr(/^\(\)/, ...regex));
}

//Usage:
//Original:
console.log(/abcd(?:ef[+A-Z0-9]gh)+$/.source);
//Same as:
console.log(
  combineRegex(
    /ab/,
    /cd/,
    [
      /()?:ef/,
      {"": [/]+A-Z/, /0-9/]},
      /gh/
    ],
    /()+$/
  ).source
);


0

@ हैशब्रोर्न का शानदार जवाब मुझे सही रास्ते पर मिला। यहाँ मेरा संस्करण है, जो इस ब्लॉग से प्रेरित है ।

function regexp(...args) {
  function cleanup(string) {
    // remove whitespace, single and multi-line comments
    return string.replace(/\s+|\/\/.*|\/\*[\s\S]*?\*\//g, '');
  }

  function escape(string) {
    // escape regular expression
    return string.replace(/[-.*+?^${}()|[\]\\]/g, '\\$&');
  }

  function create(flags, strings, ...values) {
    let pattern = '';
    for (let i = 0; i < values.length; ++i) {
      pattern += cleanup(strings.raw[i]);  // strings are cleaned up
      pattern += escape(values[i]);        // values are escaped
    }
    pattern += cleanup(strings.raw[values.length]);
    return RegExp(pattern, flags);
  }

  if (Array.isArray(args[0])) {
    // used as a template tag (no flags)
    return create('', ...args);
  }

  // used as a function (with flags)
  return create.bind(void 0, args[0]);
}

इसे इस तरह उपयोग करें:

regexp('i')`
  //so this is a regex

  //here I am matching some numbers
  (\d+)

  //Oh! See how I didn't need to double backslash that \d?
  ([a-z]{1,3}) /*note to self, this is group #2*/
`

इस RegExpऑब्जेक्ट को बनाने के लिए :

/(\d+)([a-z]{1,3})/i
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.