स्ट्रिंग चर का उपयोग कर मक्खी पर RegExps बनाएँ


138

कहो कि मैं निम्नलिखित पुन: प्रयोज्य बनाना चाहता था:

function replace_foo(target, replacement) {
   return target.replace("string_to_replace",replacement);
}

मैं ऐसा कुछ कर सकता हूं:

function replace_foo(target, string_to_replace, replacement) {
   return target.replace(string_to_replace,replacement);
}

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

function replace_foo(target, string_to_replace, replacement) {
   return target.replace(/^string_to_replace/,replacement);
}

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

function replace_foo(target, string_to_replace, replacement) {
   var regex = "/^" + string_to_replace + "/";
   return target.replace(regex,replacement);
}

जवाबों:


215

नहीं है new RegExp(string, flags), जहां flagsकर रहे हैं gया i। इसलिए

'GODzilla'.replace( new RegExp('god', 'i'), '' )

का मूल्यांकन करता है

zilla

31
और /इस फॉर्म का उपयोग करते समय रेगेक्स सीमांकक को भी छोड़ दें।
cdhowie

111

स्ट्रिंग शाब्दिक के साथ यह काफी आसान है।

ज़रुरी नहीं! उदाहरण केवल की पहली घटना को प्रतिस्थापित करता है string_to_replace। अधिक सामान्यतः आप सभी घटनाओं को बदलना चाहते हैं, इस स्थिति में, आपको स्ट्रिंग को एक वैश्विक ( /.../g) RegExp में बदलना होगा । new RegExpकंस्ट्रक्टर का उपयोग करके आप इसे स्ट्रिंग से कर सकते हैं :

new RegExp(string_to_replace, 'g')

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

function escapeRegExp(s) {
    return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
}

यह भी ध्यान रखें कि जब आप में एक रेगुलर एक्सप्रेशन का उपयोग करें कि replace(),, प्रतिस्थापन स्ट्रिंग अब भी विशेष वर्ण है $। यह भी बचना चाहिए अगर आप $अपने प्रतिस्थापन पाठ में शाब्दिक होना चाहते हैं !

function escapeSubstitute(s) {
    return s.replace(/\$/g, '$$$$');
}

(चार $एस क्योंकि वह खुद एक प्रतिस्थापन स्ट्रिंग है - अर्ग!)

अब आप RegExp के साथ वैश्विक स्ट्रिंग प्रतिस्थापन को लागू कर सकते हैं:

function replace_foo(target, string_to_replace, replacement) {
    var relit= escapeRegExp(string_to_replace);
    var sub= escapeSubstitute(replacement);
    var re= new RegExp(relit, 'g');
    return target.replace(re, sub);
}

क्या मुसीबत है। सौभाग्य से अगर आप सब करना चाहते हैं, तो स्ट्रेट स्ट्रिंग को रीगेक्स के अतिरिक्त भागों के साथ बदल दिया जाता है, एक तेज़ तरीका है:

s.split(string_to_replace).join(replacement)

...और बस यही। यह आमतौर पर समझा जाने वाला मुहावरा है।

मैं सब कुछ प्रतिस्थापित करना चाहता हूं, लेकिन string_to_replace

इसका क्या मतलब है, आप स्ट्रिंग के खिलाफ एक मैच में भाग नहीं लेने वाले पाठ के सभी हिस्सों को बदलना चाहते हैं? ^निश्चित रूप से एक प्रतिस्थापन यह नहीं करता है, क्योंकि ^इसका मतलब है एक स्टार्ट-ऑफ-स्ट्रिंग टोकन, एक नकार नहीं। ^केवल []चरित्र समूहों में एक नकार है । नकारात्मक लुकहैड्स भी हैं (?!...), लेकिन जेस्क्रिप्ट में इसके साथ समस्याएं हैं इसलिए आपको आमतौर पर इससे बचना चाहिए।

आप स्ट्रिंग के बीच 'सब कुछ' का मिलान करने का प्रयास कर सकते हैं, और मिलान स्ट्रिंग के बीच किसी भी खाली खिंचाव को छोड़ने के लिए फ़ंक्शन का उपयोग कर सकते हैं:

var re= new RegExp('(.*)($|'+escapeRegExp(string_to_find)+')')
return target.replace(re, function(match) {
    return match[1]===''? match[2] : replacement+match[2];
});

यहाँ, फिर से, एक विभाजन सरल हो सकता है:

var parts= target.split(string_to_match);
for (var i= parts.length; i-->0;)
    if (parts[i]!=='')
        parts[i]= replacement;
return parts.join(string_to_match);

10

जैसा कि दूसरों ने कहा है, new RegExp(pattern, flags)ऐसा करने के लिए उपयोग करें। यह ध्यान देने योग्य है कि आप इस कंस्ट्रक्टर में स्ट्रिंग शाब्दिक होंगे, इसलिए हर बैकस्लैश से बचना होगा। यदि, उदाहरण के लिए, आप चाहते थे कि आपका रेगेक्स बैकस्लैश से मेल खाए, तो आपको कहना होगा new RegExp('\\\\'), जबकि रेगेक्स शाब्दिक केवल होना चाहिए /\\/। इस बात पर निर्भर करता है कि आप इसे कैसे उपयोग करना चाहते हैं, आपको पर्याप्त प्रीप्रोसेसिंग (विशेष वर्णों से बचने, आदि) के बिना इस तरह के फ़ंक्शन के लिए उपयोगकर्ता इनपुट पास करने से सावधान रहना चाहिए। इसके बिना, आपके उपयोगकर्ताओं को कुछ बहुत अप्रत्याशित परिणाम मिल सकते हैं।


3
यह उत्तर, जबकि सबसे विस्तृत नहीं है, एक महत्वपूर्ण विवरण का उल्लेख करता है जो मैं सिर्फ एक घंटे के लिए अटक गया था: किसी भी विशेष अनुक्रम से बचें। उदाहरण के लिए, मैं एक निश्चित अवधि के साथ शुरू होने वाले शब्द की खोज कर रहा था, इसलिए मुझे जो regex की आवश्यकता होगी /\b[term]\B/, लेकिन इसका निर्माण करते समय मुझे कॉल करने की आवश्यकता है new RegExp("\\b"+ term + "\\B")। छोटे लेकिन महत्वपूर्ण अंतर है, और मुश्किल का उपयोग कर के रूप में एक regex सीधे के बाद से पहचानना करता अपेक्षा के अनुरूप काम करते हैं।
Byson


0

मुझे लगता है कि मेरे पास स्ट्रिंग में हाइलाइट टेक्स्ट के लिए बहुत अच्छा उदाहरण है (यह रजिस्टर में नहीं दिखता है लेकिन रजिस्टर का उपयोग करके हाइलाइट किया गया है)

function getHighlightedText(basicString, filterString) {

    if ((basicString === "") || (basicString === null) || (filterString === "") || (filterString === null)) return basicString;

    return basicString.replace(new RegExp(filterString.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\\\$&'), 'gi'),
        function(match)
            {return "<mark>"+match+"</mark>"});

}

http://jsfiddle.net/cdbzL/1258/


0

इसका एक बहुत ही सरल उपाय यह है:

function replace(target, string_to_replace, replacement) {
  return target.split(string_to_replace).join(replacement);
}

रेगेक्स की कोई आवश्यकता नहीं है

यह आधुनिक ब्राउज़रों पर भी सबसे तेज़ लगता है https://jsperf.com/replace-vs-split-join-vs-replaceall

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