2013-03-28 28 views
9

मैं सभी स्ट्रिंग ~ से घिरा तार में - द्वारा संलग्न हैं प्रतिस्थापित करना चाहते हैं से घिरा है regex की जगह नहीं है, लेकिन इस स्ट्रिंग फिर * से घिरा है नहीं तो।अगर यह एक चरित्र

एक उदाहरण है, इस स्ट्रिंग के रूप में ...

The -quick- *brown -f-ox* jumps. 

... हो जाना चाहिए ...

The ~quick~ *brown -f-ox* jumps. 

हम देखते हैं - केवल प्रतिस्थापित अगर यह *<here>* के भीतर नहीं है।

मेरे अब के लिए जावास्क्रिप्ट-regex (जो कोई ध्यान है या नहीं * से घिरा रहा है या नहीं लेता है):

var message = source.replace(/-(.[^-]+?)-/g, "~$1~"); 

संपादित करें: ध्यान दें कि यह मामला * रों विषम संख्या में है कि हो सकता है ।

+7

डाउनवोट क्यों? – poitroae

+0

yup मैं आश्चर्यचकित हूं, इतना अच्छा सवाल है। – Jai

+2

* वर्णों की विषम संख्या कब होती है? जैसे '* -क्विक- * ब्राउन * -एफ-बैल * कूदता है *। 'कौन सा' -' अक्षर प्रतिस्थापित किया जाना चाहिए और क्यों? –

उत्तर

2

यह नियमित अभिव्यक्तियों के साथ एक मुश्किल प्रकार की बात है। मुझे लगता है कि मैं क्या चाहता हूँ कुछ इस तरह है:

var msg = source.replace(/(-[^-]+-|\*[^*]+\*)/g, function(_, grp) { 
    return grp[0] === '-' ? grp.replace(/^-(.*)-$/, "~$1~") : grp; 
}); 

jsFiddle Demo

कि के लिए लग रहा है या तो- या * समूहों, और केवल धराशायी वालों पर स्थानापन्न निष्पादित। सामान्य रूप से, "घोंसले" वाक्यविन्यास नियमित अभिव्यक्तियों के साथ चुनौतीपूर्ण (या असंभव) होते हैं। (और सवाल नोटों पर एक टिप्पणी के रूप में निश्चित रूप से, वहाँ विशेष मामलों — झूलने अक्षरों से परे — कि यह बहुत मुश्किल है।)

+1

कार्य उदाहरण: http://jsfiddle.net/Zb6BU/ - यह सुनिश्चित नहीं है कि यह वोट क्यों नहीं उठा रहा है, यह केवल इरादे के अनुसार काम करता है! +1 –

+0

@mcpDESIGNS: अन्य उत्तर भी काम कर रहे हैं :-) – Bergi

+0

@ बर्गि मैं अब देखता हूं, सभी के लिए +1 है :) हाहा –

1

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

'The -quick- *brown -f-ox* jumps.' 
    .split('*') 
    .map(function(item, index, arr) { 
     if (index % 2) { 
      if (index < arr.length - 1) { 
       return item; // balanced 
      } 
      // not balanced 
      item = '*' + item; 
     } 
     return item.replace(/\-([^-]+)\-/, '~$1~'); 
    }) 
    .join(''); 

Demo

+0

क्या होगा यदि स्ट्रिंग में '*' है जो एक जोड़ी का हिस्सा नहीं है? जैसे '' -क्विक- * ब्राउन-एफ-बैल कूदता है। 'अगर मैं सही ढंग से समझता हूं, तो इस मामले में' -क्विच 'और' -एफ-'दोनों को प्रतिस्थापित किया जाना चाहिए, लेकिन केवल '-क्विक-' होगा। –

+0

@ केएनबी यह मान लेगा कि सितारे अच्छी तरह से संतुलित हैं :) –

+0

संदर्भ के आधार पर, यह एक बहुत बड़ी धारणा है। –

1

पता लगाना है कि क्या एक मैच कुछ सीमांकक से घिरा नहीं है एक बहुत जटिल काम है - this example भी देखें। Lookaround मदद कर सकता है, लेकिन जेएस केवल लुकहेड का समर्थन करता है। तो हम फिर से लिखने सकता है "~ से घिरा हुआ नहीं" से "सम संख्या के बाद या ~", और उस पर मैच:

source.replace(/-([^-]+)-(?=[^~]*([^~]*~[^~]*~)*$)/g, "~$1~"); 

लेकिन बेहतर हम, दोनों - और * पर से मेल खाते हैं ताकि हम साथ ही * रों में लिपटे कुछ भी उपभोग और उसके बाद एक कॉलबैक फ़ंक्शन में तय कर सकते हैं यह नहीं बदलने के लिए:

source.replace(/-([^-]+)-|\*([^*]+)\*/g, function(m, hyp) { 
    if (hyp) // the first group has matched 
     return "~"+hyp+"~"; 
    // else let the match be unchanged: 
    return m; 
}); 

यह बेहतर निर्दिष्ट करने के लिए सक्षम होने का लाभ दिया है "संलग्न", उदा।अमान्य पैटर्न के बेहतर संचालन के लिए "अंदर" पर शब्द सीमाएं जोड़कर, उदाहरण के लिए @ मारस द्वारा वर्णित * वर्णों की विषम संख्या) - वर्तमान रेगेक्स में अगले दो उपस्थितियां होती हैं।

0

जैक के बहुत स्पष्ट उत्तर का एक terser संस्करण।

source.split(/(\*[^*]*\*)/g).map(function(x,i){ 
return i%2?x:x.replace(/-/g,'~'); 
}).join(''); 

काम करने के लिए, चीयर्स लगता है।

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