2010-12-06 18 views
98

कहें कि मैं निम्नलिखित पुनः उपयोग करने योग्य बनाना चाहता हूं:क्या आप स्ट्रिंग चर का उपयोग कर फ्लाई पर जावास्क्रिप्ट regexes बना सकते हैं?

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); 
} 

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

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

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

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

उत्तर

153

वहाँ new RegExp(string, flags) जहां flagsg या i हैं: कुछ इस तरह महान अगर सब पर संभव हो जाएगा। तो

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

zilla 
+22

और छोड़ देते हैं पर सबसे तेजी से हो रहा है पर regexes के लिए कोई ज़रूरत नहीं इस फॉर्म का उपयोग करते समय '/' regex delimiters भी। – cdhowie

+0

धन्यवाद मध्यस्थ। और cdhowie: महान टिप्पणी। मैंने पहले दूसरी तरफ कोशिश की होगी। बचने के किसी विशेष दृश्यों: – buley

9

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

+2

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

97

स्ट्रिंग अक्षर के साथ यह काफी आसान है।

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

new RegExp(string_to_replace, 'g') 

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

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

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

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

(चार $ रों क्योंकि अपने आप में एक प्रतिस्थापन स्ट्रिंग-अरे यह है कि!)

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

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); 
} 

क्या एक दर्द। सौभाग्य से यदि एक सीधे स्ट्रिंग regex का कोई अतिरिक्त भागों के साथ की जगह है सब आप क्या करना चाहते, वहाँ एक तेज तरीका है:

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); 
+9

+1, बहुत अच्छी तरह से, और सराहना की। –

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

संबंधित मुद्दे

 संबंधित मुद्दे