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?

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)

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"

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.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.