उपयोगकर्ता इनपुट स्ट्रिंग को नियमित अभिव्यक्ति में परिवर्तित करना


333

मैं HTML और जावास्क्रिप्ट में एक नियमित अभिव्यक्ति परीक्षक डिजाइन कर रहा हूं। उपयोगकर्ता रेडियो बटन के माध्यम से एक regex, एक स्ट्रिंग दर्ज करेगा, और वे फ़ंक्शन का चयन करना चाहते हैं (जैसे खोज, मिलान, प्रतिस्थापित, आदि) और प्रोग्राम उस परिणाम को प्रदर्शित करेगा जब उस फ़ंक्शन को निर्दिष्ट तर्कों के साथ चलाया जाता है। स्वाभाविक रूप से अतिरिक्त तर्कों को प्रतिस्थापित करने के लिए अतिरिक्त पाठ बॉक्स होंगे और ऐसे।

मेरी समस्या उपयोगकर्ता से स्ट्रिंग हो रही है और इसे एक नियमित अभिव्यक्ति में बदल रही है। अगर मैं कहता हूं कि उन्हें //उनके द्वारा दर्ज किए गए रेक्स के आसपास की जरूरत नहीं है , तो वे झंडे, जैसे gऔर सेट नहीं कर सकते i। इसलिए उन्हें //अभिव्यक्ति के आस- पास होना चाहिए , लेकिन मैं उस स्ट्रिंग को एक रेक्सएक्स में कैसे बदल सकता हूं? यह एक स्ट्रिंग के बाद से शाब्दिक नहीं हो सकता है, और मैं इसे RegExp कंस्ट्रक्टर को पास नहीं कर सकता, क्योंकि यह स्ट्रिंग के बिना नहीं है //। क्या रीजैक्स में उपयोगकर्ता इनपुट स्ट्रिंग बनाने का कोई अन्य तरीका है? क्या मुझे regex की स्ट्रिंग और झंडे को पार्स करना होगा और //फिर इसे दूसरे तरीके से बनाना होगा? क्या मुझे उन्हें एक स्ट्रिंग में दर्ज करना चाहिए, और फिर अलग से झंडे दर्ज करना चाहिए?

जवाबों:


611

स्ट्रिंग से एक नियमित अभिव्यक्ति बनाने के लिए RegExp ऑब्जेक्ट कंस्ट्रक्टर का उपयोग करें :

var re = new RegExp("a|b", "i");
// same as
var re = /a|b/i;

1
इनपुट फ़ील्ड के साथ ऑनलाइन टूल रखना अच्छा होगा
बजे

61
इस तरह से करते समय, आपको बैकस्लैश से बचना चाहिए, जैसेvar re = new RegExp("\\w+");
JD स्मिथ

12
@holms regex101.com एक महान regex ऑनलाइन उपकरण के रूप में अच्छी तरह से है
फ्रान हेरेरो

2
मुझे यह देखने में
थोड़ा

2
@ JDSmith इसका मतलब मैं आपके उदाहरण में नहीं था। मेरा मतलब था कि आपको दोहरे उद्धरण चिह्नों से बचने की आवश्यकता है यदि आप उन्हें रेगेक्स का हिस्सा बनाना चाहते हैं बशर्ते कि यह कठिन कोडित हो। जाहिर है, यह किसी भी लागू नहीं होता है अगर स्ट्रिंग एक <input>HTML टैग की तरह चर में है । var re = new RegExp("\"\\w+\"");RegExp कंस्ट्रक्टर का उपयोग करके हार्ड कोडित रेगेक्स का एक उदाहरण है और दोहरे उद्धरण चिह्नों से बचना आवश्यक है। एक चर में एक स्ट्रिंग से मेरा मतलब है कि आप बस कर सकते हैं var re = new RegExp(str);और strएक समस्या के बिना दोहरे उद्धरण या बैकस्लैश हो सकते हैं।
लुइस पाउलो

66
var flags = inputstring.replace(/.*\/([gimy]*)$/, '$1');
var pattern = inputstring.replace(new RegExp('^/(.*?)/'+flags+'$'), '$1');
var regex = new RegExp(pattern, flags);

या

var match = inputstring.match(new RegExp('^/(.*?)/([gimy]*)$'));
// sanity check here
var regex = new RegExp(match[1], match[2]);

आपको यह विचार करना चाहिए कि अमान्य इनपुट /\/को मान्यता दी गई है।
Gumbo

8
या RegExp कंस्ट्रक्टर को एक जटिल पार्सर लिखने के बजाय, "नियमित अभिव्यक्ति में अनुगामी" विफल होने दें।
अनाम

21

यहाँ एक लाइनर है: str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')

मैंने इसे एस्केप-स्ट्रिंग-रेगेक्सपी एनपीएम मॉड्यूल से प्राप्त किया।

इसे आजमा रहे हैं:

escapeStringRegExp.matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
function escapeStringRegExp(str) {
    return str.replace(escapeStringRegExp.matchOperatorsRe, '\\$&');
}

console.log(new RegExp(escapeStringRegExp('example.com')));
// => /example\.com/

झंडे समर्थन के साथ टैग किए गए टेम्पलेट शाब्दिक का उपयोग करना:

function str2reg(flags = 'u') {
    return (...args) => new RegExp(escapeStringRegExp(evalTemplate(...args))
        , flags)
}

function evalTemplate(strings, ...values) {
    let i = 0
    return strings.reduce((str, string) => `${str}${string}${
        i < values.length ? values[i++] : ''}`, '')
}

console.log(str2reg()`example.com`)
// => /example\.com/u

15

जावास्क्रिप्ट RegExp ऑब्जेक्ट कंस्ट्रक्टर का उपयोग करें ।

var re = new RegExp("\\w+");
re.test("hello");

आप कंस्ट्रक्टर को दूसरे स्ट्रिंग तर्क के रूप में झंडे पास कर सकते हैं। विवरण के लिए दस्तावेज देखें।


9

मेरे मामले में उपयोगकर्ता इनपुट somethimes delimiters और कभी कभी नहीं द्वारा व्यर्थ था। इसलिए मैंने एक और मामला जोड़ा है।

var regParts = inputstring.match(/^\/(.*?)\/([gim]*)$/);
if (regParts) {
    // the parsed pattern had delimiters and modifiers. handle them. 
    var regexp = new RegExp(regParts[1], regParts[2]);
} else {
    // we got pattern string without delimiters
    var regexp = new RegExp(inputstring);
}

3
आप हमेशा .split()लंबे रेगेक्स स्ट्रिंग के बजाय फ़ंक्शन का उपयोग कर सकते हैं । regParts = inputstring.split('/')यह regParts[1]रेगेक्स स्ट्रिंग बना देगा , और regParts[2]डेलिमिटर (रेगेक्स की स्थापना मान रहा है /.../gim)। आप देख सकते हैं कि क्या वहाँ के साथ सीमांकक हैं regParts[2].length < 0
Jaketr00

3

मेरा सुझाव है कि आप विशेष झंडे के लिए अलग चेकबॉक्स या एक टेक्स्टफील्ड भी जोड़ सकते हैं। इस तरह यह स्पष्ट है कि उपयोगकर्ता को कोई भी जोड़ने की आवश्यकता नहीं है //। एक प्रतिस्थापन के मामले में, दो टेक्स्टफील्ड प्रदान करें । इससे आपकी जिंदगी काफी आसान हो जाएगी।

क्यों? क्योंकि अन्यथा कुछ उपयोगकर्ता जोड़ देंगे //जबकि अन्य नहीं करेंगे। और कुछ सिंटैक्स त्रुटि करेगा। फिर, आपके द्वारा छीन लिए जाने के बाद //, आप एक सिंटैक्टिक रूप से मान्य रेगेक्स के साथ समाप्त हो सकते हैं जो उपयोगकर्ता के लिए ऐसा कुछ नहीं है, जो अजीब व्यवहार (उपयोगकर्ता के दृष्टिकोण से) के लिए अग्रणी है।


2

यह तब भी काम करेगा जब स्ट्रिंग अमान्य है या झंडे आदि नहीं हैं:

function regExpFromString(q) {
  let flags = q.replace(/.*\/([gimuy]*)$/, '$1');
  if (flags === q) flags = '';
  let pattern = (flags ? q.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1') : q);
  try { return new RegExp(pattern, flags); } catch (e) { return null; }
}

console.log(regExpFromString('\\bword\\b'));
console.log(regExpFromString('\/\\bword\\b\/gi'));
            


2

यदि आप वास्तव में एक स्ट्रिंग को रेगेक्स में बदलना चाहते हैं, तो निम्न फ़ंक्शन का उपयोग करके देखें:

function String2Regex(s){return new RegExp(s.match(/\/(.+)\/.*/)[1], s.match(/\/.+\/(.*)/)[1]);}

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

"abc".match(String2Regex("/a/g"))
> ["a"]

संदर्भ के लिए, यहाँ स्वरूपित और अधिक आधुनिक संस्करण है:

const String2Regex = str => {
  // Main regex
  const main = str.match(/\/(.+)\/.*/)[1]

  // Regex options
  const options = str.match(/\/.+\/(.*)/)[1]

  // Return compiled regex
  return new RegExp(main, options)
}

1

पहले के उत्तर के लिए धन्यवाद, यह ब्लॉक एक रेग्युरेबल स्ट्रिंग को एक RegEx में लगाने के लिए एक सामान्य उद्देश्य समाधान के रूप में अच्छी तरह से कार्य करता है .. पाठ को छानने के लिए:

var permittedChars = '^a-z0-9 _,.?!@+<>';
permittedChars = '[' + permittedChars + ']';

var flags = 'gi';
var strFilterRegEx = new RegExp(permittedChars, flags);

log.debug ('strFilterRegEx: ' + strFilterRegEx);

strVal = strVal.replace(strFilterRegEx, '');
// this replaces hard code solt:
// strVal = strVal.replace(/[^a-z0-9 _,.?!@+]/ig, '');

1

आप चेकबॉक्स का उपयोग कर झंडे के लिए पूछ सकते हैं तो कुछ इस तरह से करें:

var userInput = formInput;
var flags = '';
if(formGlobalCheckboxChecked) flags += 'g';
if(formCaseICheckboxChecked) flags += 'i';
var reg = new RegExp(userInput, flags);

की तरह दिखता है रेगुलर एक्सप्रेशन से अनुगामी याद आ रही है पी .. ढेर नहीं जाने देंगे मुझे एक 1 चरित्र संपादन कर लेने
जीन बो

-3

मैं उपयोग करता हूं eval इस समस्या को हल करने के लिए करता ।

उदाहरण के लिए:

    function regex_exec() {

        // Important! Like @Samuel Faure mentioned, Eval on user input is a crazy security risk, so before use this method, please take care of the security risk. 
        var regex = $("#regex").val();

        // eval()
        var patt = eval(userInput);

        $("#result").val(patt.exec($("#textContent").val()));
    }

3
userInput पर eval एक पागल सुरक्षा जोखिम है
शमूएल Faure

1
श्री बॉबी टेबल!
लुइज़ फेलिप
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.