Jak przekształcić wyrażenie regularne w niechciane?

226

Korzystam z jQuery. Mam ciąg znaków z blokiem znaków specjalnych (początek i koniec). Chcę pobrać tekst z tego bloku znaków specjalnych. Użyłem obiektu wyrażenia regularnego do znalezienia ciągu. Ale jak mogę powiedzieć jQuery, aby znalazł wiele wyników, jeśli mają dwie lub więcej znaków specjalnych?

Mój 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>

i mój kod JavaScript:

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

  alert(filterdata); 

  //end write js 
});

Mój wynik to: [| cơ thử | nghiệm |] thị trường [| test2 | đây là test lần 2 |] chứng khoán [| Mỹ | day la nuoc my |] . Ale to nie jest wynik, który chcę :(. Jak zdobyć [tekst] dla czasów 1 i [demo] dla czasów 2?


Właśnie skończyłem pracę po wyszukaniu informacji w Internecie ^^. Tworzę kod w ten sposób:

var filterdata = takedata.match(/(\[.*?\])/g);
  • mój wynik to: [| cơ thử | nghiệm |], [| test2 | đây là test w 2 |] to prawda !. ale tak naprawdę tego nie rozumiem. Czy możesz mi odpowiedzieć dlaczego?
Rueta
źródło

Odpowiedzi:

491

Nie chciwe modyfikatory wyrażenia regularnego są jak ich chciwe odpowiedniki, ale ?natychmiast po nich następują:

*  - zero or more
*? - zero or more (non-greedy)
+  - one or more
+? - one or more (non-greedy)
?  - zero or one
?? - zero or one (non-greedy)
Asaf
źródło
29
warto zauważyć, że sam ?w sobie oznacza „jeden lub zero” (ale jest chciwy!). Np. 'bb'.replace(/b?/, 'a') //'ab'I'bb'.replace(/c?/, 'a') //'abb'
Hashbrown
1
jak c nic tam nie pasowało
Muhammad Umer
1
@MuhammadUmer Myślę, że sugerował to, ponieważ cnie pasuje, ale ty masz ?, to znaczy 0 or 1, że będzie pasować 0 number of c characters, a więc zastąpi go. Nie mam jednak pojęcia, jak to działa, ponieważ nie można go skompilować w żadnym silniku regularnym, który wypróbowałem 😢
Noctis
35

Masz rację, że chciwość jest problemem:

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

Jeśli chcesz dopasować oba A--Z, musisz użyć A.*?Z( ?sprawia, że *„niechętny” lub leniwy).

Są jednak czasem lepsze sposoby na to, np

A[^Z]*+Z

Wykorzystuje zanegowaną klasę znaków i kwantyfikator dzierżawczy w celu ograniczenia cofania i prawdopodobnie będzie bardziej wydajny.

W twoim przypadku regex byłby:

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

Niestety, wyrażenia regularne JavaScript nie obsługują kwantyfikatora dzierżawczego, więc musisz po prostu zrobić z:

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

Zobacz też


Szybkie podsumowanie

*   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

Zauważ, że kwantyfikatory niechętne i dzierżawcze mają również zastosowanie do {n,m}konstrukcji o powtarzalnych ograniczeniach .

Przykłady w Javie:

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"
środki smarujące wielotlenowe
źródło
kopiuję wyrażenie regularne do mojej pracy, a wynik to: nieprawidłowy kwantyfikator + \]) [Przerwa na tym błędzie] var filterdata = takedata.match (/ (\ [[^ \]] ++ \]) /); \ n ( firebugs + Firefox) coś nie tak?
Rueta
@Reta: najwyraźniej smak Javascript nie obsługuje zaborczego. Zredagowałem swoją odpowiedź, aby odzwierciedlić ten fakt. Możesz użyć jednego +zamiast dwóch.
polygenelubrykanty
1
Chociaż zamiast atomowych kwantyfikatorów można stosować grupy atomowe, JavaScript również nie obsługuje grup atomowych. Ale istnieje trzecia alternatywa, patrz: instanceof.me/post/52245507631/... -you can emulate atomic grouping with LookAhead. (?>a) becomes (?=(a))\1
Roland Pihlakas
2
To jest odpowiedź Java na pytanie JavaScript i Java! = JavaScript. Czytelnicy, zwróćcie uwagę.
Roshambo,
3

Wierzę, że tak by było

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

gna końcu oznacza globalne, więc nie kończy się na pierwszym meczu.

iangraham
źródło
tak, masz rację w / g. właśnie wykonałem swoją pracę z twoją odpowiedzią / g ^^. Ale kiedy robię regularne /(\[.+\])/g mój wynik to: [| cơ thử | nghiệm |] thị trường [| test2 | đây là test lần 2 |] chứng khoán [| Mỹ | day la nuoc my |] :(
Rueta