2017-11-28 2 views
2

Entschuldigung, wenn ich einige Fehler gemacht habe, während ich meine erste Frage hier posten.Javascript Regex zwei Arten von Trennzeichen erfassen als eine Gruppe

Ich hatte ein Problem, während ich mit Javascript lodash Vorlage arbeitete. Ich habe versucht, Regex für auszuwerten Trennzeichen neu zu schreiben, so dass es zwei Arten von Trennzeichen akzeptieren und es als eine Gruppe erfassen konnte.

Zuerst habe ich versucht, zwei tun zwei Gruppen

/<%([\s\S]+?)%>|{{([\s\S]+?)}}/ 

aber ich am Ende zwei Gruppen, dann habe ich versucht,

/(?:<%|{{)([\s\S]+?)(?:%>|}})/ 

Es funktionierte und nahmen zwei Gruppen ein, aber es funktionierte für einige Fälle das sollte funktionieren
nicht Zum Beispiel:

<% 
    text1 
%> //should work 
{{ text2 }} //should work 
<% text2 }} // shouldn't work 

Gibt es eine Möglichkeit, mit mehreren Trennzeichen übereinzustimmen, aber nur eine Gruppe zu erfassen?

+0

etwas Ähnliches könnte mit Rückreferenz (etwas wie '(['"]) [^' ​​"] + \ 1') getan werden. aber da sich das schließende Trennzeichen vom Öffnen unterscheidet, glaube ich, dass es unmöglich ist – skyboyer

Antwort

0

Sie können das erreichen mit Lookaheads:

const regex = /(?:<%(?=.*%>)|{{(?=.*}}))(.+)(?:}}|%>)/ 
 

 
console.log(regex.test('<% Hello World %>')) // true 
 
console.log(regex.test('{{ Hello World }}')) // true 
 
console.log(regex.test('<% Hello World }}')) // false 
 
console.log(regex.test('{{ Hello World %>')) // false

Try it on regex101.com!

+0

Sieht so aus, als würde es Übereinstimmungen finden, aber leider erfasst es keine Gruppe. Danke, ich denke, ich muss fortgeschrittene Lookaheads lernen – danziamo

+0

@danziamo Ich habe eine Capturing-Gruppe um '. +' Hinzugefügt, die den Inhalt zwischen den Delimitern als erste Gruppe erfassen soll. – Timo

+0

Fast funktioniert, aber eine Sache übrig, das wäre sehr hilfreich zu beheben. Es erfasst eine Gruppe, aber Delimiter sind innerhalb enthalten, ist es möglich, Text ohne Trennzeichen innerhalb zu erfassen? – danziamo

0

Sie haben Lookaheads verwenden:

(?:<%(?=[^<>]*%>)|{{(?=[^{}]*}}))(.+?)(?:%>|}}) 

Live demo

+0

Danke für die Antwort. Es gibt ein Problem für den Fall <% text 2}} {{text 3%> – danziamo

0

Eine andere vielleicht etwas einfachere Alternative:

var l = console.log, r = /<%.+?%>|{{.+?}}/, f = s => (s.match(r) + '').slice(2, -2) 
 

 
l(f('<% a %>')) // " a " 
 
l(f('{{ b }}')) // " b " 
 
l(f('<% c }}')) // "" 
 
l(f('{{ d %>')) // ""

Das sich wiederholende Muster auch ersetzt werden kann, aber das ist vielleicht ein bisschen zu viel des Guten:

var l = console.log, r = new RegExp('<%1%>|{{1}}'.split(1).join`([\\s\\S]+?)`), m 
 

 
f = s => (m = s.match(r)) ? m[1] || m[2] : '' 
 

 
l(r)   // /<%([\s\S]+?)%>|{{([\s\S]+?)}}/ 
 
l(f('<% a %>')) // " a " 
 
l(f('{{ b }}')) // " b " 
 
l(f('<% c }}')) // "" 
 
l(f('{{ d %>')) // ""

+0

Danke für die Antwort, aber ich musste auch Text zwischen Trennzeichen erfassen. Und gefangener Text zwischen verschiedenen Arten von Trennzeichen sollte als eine Gruppe betrachtet werden, und in diesem Beispiel fürchte ich, dass er zwei erfasste Gruppen zurückgibt – danziamo

Verwandte Themen