Wie macht man aus regulärem Ausdruck nicht gierig?

227

Ich benutze jQuery. Ich habe eine Zeichenfolge mit einem Block von Sonderzeichen (Anfang und Ende). Ich möchte den Text aus diesem Sonderzeichenblock erhalten. Ich habe ein Objekt mit regulären Ausdrücken für die Suche nach Zeichenfolgen verwendet. Aber wie kann ich jQuery anweisen, mehrere Ergebnisse zu finden, wenn zwei oder mehr Sonderzeichen vorhanden sind?

Mein HTML:

<div id="container">
    <div id="textcontainer">
     Cuc chiến pháp lý gia [|cơ thử|nghim|] th trường [|test2|đây là test ln 2|] chng khoán [|Mỹ|day la nuoc my|] và ngân hàng đầu tư quyn lc nht Ph Wall mi ch bt đầu.
    </div>
</div>

und mein JavaScript-Code:

$(document).ready(function() {
  var takedata = $("#textcontainer").text();
  var test = 'abcd adddb';
  var filterdata = takedata.match(/(\[.+\])/);

  alert(filterdata); 

  //end write js 
});

Mein Ergebnis ist: [| cơ thử | nghiệm |] thị trường [| test2 | đây là test lần 2 |] chứng khoán [| Mỹ | day la nuoc my |] . Aber das ist nicht das Ergebnis, das ich will :(. Wie bekomme ich [Text] für Zeit 1 und [Demo] für Zeit 2?


Ich habe gerade meine Arbeit erledigt, nachdem ich Informationen im Internet gesucht habe ^^. Ich mache Code wie folgt:

var filterdata = takedata.match(/(\[.*?\])/g);
  • Mein Ergebnis ist: [| cơ thử | nghiệm |], [| test2 | đây là test lần 2 |] das ist richtig!. aber ich verstehe das nicht wirklich. Kannst du mein Warum beantworten?
Rueta
quelle

Antworten:

492

Die nicht-gierigen Regex-Modifikatoren sind wie ihre gierigen Gegenstücke, aber mit einem ?unmittelbar folgenden:

*  - zero or more
*? - zero or more (non-greedy)
+  - one or more
+? - one or more (non-greedy)
?  - zero or one
?? - zero or one (non-greedy)
Asaph
quelle
29
Es könnte nützlich sein zu bemerken, dass dies ?für sich genommen "Eins oder Null" bedeutet (aber gierig ist!). ZB 'bb'.replace(/b?/, 'a') //'ab'und'bb'.replace(/c?/, 'a') //'abb'
Hashbrown
1
Wie konnte ich dort nichts zusammenbringen
Muhammad Umer
1
@ MuhammadUmer Ich denke, er hat das vorgeschlagen, weil das cnicht passt , aber du hast das ?, das heißt 0 or 1, dann wird es passen 0 number of c charactersund es somit ersetzen. Ich habe keine Ahnung, wie es funktioniert, da das in keiner Regex-Engine kompiliert wird, die ich ausprobiert habe 😢
Noctis
35

Sie haben Recht, dass Gier ein Problem ist:

--A--Z--A--Z--
  ^^^^^^^^^^
     A.*Z

Wenn Sie beide übereinstimmen möchten A--Z, müssen Sie verwenden A.*?Z(das ?macht das *"widerstrebend" oder faul).

Es gibt jedoch manchmal bessere Möglichkeiten, dies zu tun, z

A[^Z]*+Z

Dies verwendet eine negierte Zeichenklasse und einen besitzergreifenden Quantifizierer, um das Backtracking zu reduzieren, und ist wahrscheinlich effizienter.

In Ihrem Fall wäre der reguläre Ausdruck:

/(\[[^\]]++\])/

Leider unterstützt Javascript Regex keinen Possessiv-Quantifizierer, sodass Sie nur Folgendes tun müssen:

/(\[[^\]]+\])/

Siehe auch


Kurze Zusammenfassung

*   Zero or more, greedy
*?  Zero or more, reluctant
*+  Zero or more, possessive

+   One or more, greedy
+?  One or more, reluctant
++  One or more, possessive

?   Zero or one, greedy
??  Zero or one, reluctant
?+  Zero or one, possessive

Es ist zu beachten, dass die widerstrebenden und besitzergreifenden Quantifizierer auch auf die {n,m}Konstrukte mit endlicher Wiederholung anwendbar sind .

Beispiele in Java:

System.out.println("aAoZbAoZc".replaceAll("A.*Z", "!"));  // prints "a!c"
System.out.println("aAoZbAoZc".replaceAll("A.*?Z", "!")); // prints "a!b!c"

System.out.println("xxxxxx".replaceAll("x{3,5}", "Y"));  // prints "Yx"
System.out.println("xxxxxx".replaceAll("x{3,5}?", "Y")); // prints "YY"
Polygenschmierstoffe
quelle
Ich kopiere Ihren regulären Ausdruck in meine Arbeit und das Ergebnis ist: ungültiger Quantifizierer + \]) [Fehler beheben] var filterdata = takedata.match (/ (\ [[^ \]] ++ \]) /); \ n ( Firebugs + Firefox) stimmt etwas nicht?
Rueta
@ Rueta: Anscheinend unterstützt Javascript nicht Possessiv. Ich habe meine Antwort bearbeitet, um diese Tatsache widerzuspiegeln. Sie können einfach eins +anstelle von zwei verwenden.
Polygenschmierstoffe
1
Obwohl Atomgruppen anstelle von Possessivquantifizierern verwendet werden können, unterstützt JavaScript die Atomgruppen ebenfalls nicht. Aber es gibt eine dritte Alternative, siehe diese: instanceof.me/post/52245507631/… -you can emulate atomic grouping with LookAhead. (?>a) becomes (?=(a))\1
Roland Pihlakas
2
Dies ist eine Java-Antwort auf eine JavaScript-Frage und Java! = JavaScript. Leser, beachten Sie.
Roshambo
3

Ich glaube, das wäre so

takedata.match(/(\[.+\])/g);

Das gam Ende bedeutet global, also hört es nicht beim ersten Spiel auf.

Iangraham
quelle
ja, du bist richtig in / g. Ich habe gerade meine Arbeit mit Ihrer Antwort / g ^^ gemacht. Aber wenn ich regelmäßig mache /(\[.+\‹)/g, ist mein Ergebnis: [| cơ thử | nghiệm |] thị trường [| test2 | đây là test lần 2 |] chứng khoán [| Mỹ | day la nuoc my |] :(
Rueta