2015-07-31 14 views
8

Sto usando regex per sostituire ( in altre espressioni regolari (o espressioni regolari?) Con (?: per trasformarle in gruppi non corrispondenti. La mia espressione presuppone che non (?X strutture vengono utilizzati e si presenta così:Sostituisci tutte le corrispondenze carattere che non sono sfuggite con barra rovesciata

(
    [^\\]  - Not backslash character 
    |^  - Or string beginning 
) 
(?: 
    [\(]  - a bracket 
) 

Purtroppo questo non funziona nel caso in cui ci sono due partite uno accanto all'altro, come in questo caso: how((\s+can|\s+do)(\s+i)?)?

image description

Con lookbehinds, la soluzione è semplice:

/(?<=[^\\]|^)[\(]/g 

Ma javascript non sup port lookbehinds, quindi cosa posso fare? Le mie ricerche non hanno portato nessuna alternativa universale facile da guardare.

risposta

2

Usa lookbehind attraverso l'inversione:

function revStr(str) { 
 
    return str.split('').reverse().join(''); 
 
} 
 

 
var rx = /[(](?=[^\\]|$)/g; 
 
var subst = ":?("; 
 

 
var data = "how((\\s+can|\\s+do)(\\s+i)?)?"; 
 
var res = revStr(revStr(data).replace(rx, subst)); 
 
document.getElementById("res").value = res;
<input id="res" />

Si noti che il modello di espressione regolare è anche invertito in modo da poter utilizzare un look-ahead al posto di un lookbehind, e la stringa di sostituzione è invertito anche. Diventa troppo complicato con espressioni regolari più lunghe, ma in questo caso non è ancora illeggibile.

0

(Edited)

esempio stringa: soluzione

how((\s+can|\s+do)(\s+i)?)? 

una linea:

o='how((\\s+can|\\s+do)(\\s+i)?)?'; 
 
alert(o.replace(/\\\(/g,9e9).replace(/\(/g,'(?:').replace(/90{9}/g,'\\('))

risultato:

how(?:(?:\s+can|\s+do)(?:\s+i)?)? 

e naturalmente funziona con stringhe come come ((\ s + \(can\) | \ s + do) (\ s + i)?)?

+0

E il primo gruppo di cattura rimane ancora. –

+0

@stribizhev forse ho frainteso l'OP. Sembra che abbiamo bisogno di un esempio del risultato completo desiderato – AwokeKnowing

+0

Credo che il risultato desiderato sia "" come (?: (?: \ S + può | \ s + do) (?: \ S + i)?)? "' . – nrabinowitz

2

Una possibilità è quella di fare una sostituzione a due passaggi, con un token (mi piace unicode per questo, in quanto è improbabile che appaiono altrove):

var s = 'how((\\s+can|\\s+do)(\\s+i)?)?'; 
 
var token = "\u1234"; 
 
// Look for the character preceding the (you want 
 
// to replace. We'll add the token after it. 
 
var patt1 = /([^\\])(?=\()/g; 
 
// The second pattern looks for the token and the (. 
 
// We'll replace both with the desired string. 
 
var patt2 = new RegExp(token + '\\(', 'g'); 
 

 
s = s.replace(patt1, "$1" + token).replace(patt2, "(?:"); 
 

 
console.log(s);

https://jsfiddle.net/48e75wqz/1/

+1

Buona soluzione, anche +1 :) Ho appena verificato l'interesse: '\ u1234 EIOIOPICO SILLABILE SEE'. –

+0

C'è un'enorme riscrittura su questo tipo di [Mimetizzare Lookbehind in JavaScript] (http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript) per ulteriori letture. –

+1

Come mi ha indicato David Conrad in [una mia risposta] (http://stackoverflow.com/a/26791459/17300), non utilizzare un _ _ carattere "improbabile" come '\ u1234' - usa un punto codice unicode che è ** non ** un carattere_ - Ora utilizzo '\ uFDD1' - dall'unicode [area uso privato] (http://www.unicode.org/faq/private_use.html#nonchar4). –

Problemi correlati