Regex: dopasowanie do pierwszego wystąpienia postaci


356

Szukam wzoru, który pasuje do wszystkiego do do pierwszego wystąpienia określonej postaci, powiedz „;” - średnik .

Ja to napisałem:

/^(.*);/

Ale tak naprawdę pasuje do wszystkiego (w tym średnika) aż do ostatniego wystąpienia średnika.


65
/^(.*?);/powinien również działać (nazywa się to nie chciwym ), ale podane odpowiedzi [^;]*są lepsze.
Pascal

jak wybrałbyś wszystko po średniku, a nie sam średnik.
Muhammad Umer,

widzisz, jak to działa, \w+(?!([^]+;)|;)ale nie dlatego? .+(?!([^]+;)|;)
Muhammad Umer,

1
Pascal, powinieneś to napisać jako odpowiedź!
Sean Kendle,

@Pascal To jest odpowiednie jako odpowiedź! Dzięki!
neverMind9

Odpowiedzi:


503

Potrzebujesz

/[^;]*/

[^;]Jest klasa znaków , która pasuje do wszystkiego oprócz średnika.

Aby zacytować stronę perlre:

Możesz określić klasę znaków, umieszczając listę znaków w [], która będzie pasować do dowolnego znaku z listy. Jeśli pierwszym znakiem po „[” jest „^”, klasa pasuje do dowolnego znaku spoza listy.

Powinno to działać w większości dialektów wyrażeń regularnych.


Świetną częścią tego rozwiązania jest to, że pasuje również do końca linii, np. W moim przypadku miałem foo=bar;baz=bax;bab=bafi pasowało bab=bafnawet tam, gdzie nie ma ;dokładnie tego, czego potrzebuję. Nie jestem pewien, dlaczego to działa, jeśli spec mówi, że pasuje do wszystkiego oprócz symbolu docelowego ...
skryvets


38

/^[^;]*/

[^;] Mówi, że pasuje do wszystkiego oprócz średnika. Nawiasy kwadratowe są operatorem dopasowywania zestawu, w zasadzie dopasowują dowolny znak w tym zestawie znaków, ^na początku powoduje odwrotne dopasowanie, więc dopasuj wszystko, co nie jest w tym zestawie.


3
Pamiętaj, że pierwsze ^ w tej odpowiedzi nadaje regexowi zupełnie inne znaczenie: sprawia, że ​​wyrażenie regularne szuka tylko dopasowań zaczynających się od początku łańcucha. W takim przypadku byłoby to efektywne, gdybyś nie uruchomił wyrażenia regularnego tylko raz. Jeśli chcesz wyszukać wiele dopasowań w jednym ciągu, pierwsze ^ musiałoby odejść.
Dan Breslau

4
Powiedział, że chce dopasować wszystko do pierwszego wystąpienia średnika, więc założyłem, że miał na myśli od początku łańcucha.
Glenn Slaven



8

przykładowy tekst:

"this is a test sentence; to prove this regex; that is g;iven below"

Jeśli na przykład mamy powyższy przykładowy tekst, regex /(.*?\;)/da ci wszystko do pierwszego wystąpienia średnika ( ;), w tym średnika:"this is a test sentence;"


3
nie trzeba uciekać od ;znaku, ponieważ nie jest to wyrażenie specjalne wyrażenia regularnego. Grupowanie również ()nie jest wymagane. Możesz iść z/.*?;/
Aliaksei Kliuchnikau

1
tak, masz całkowitą rację. ucieczka była bardziej jak „lepiej bezpiecznie niż przepraszać”
poncius

2
Oto odpowiedź, której szukałem. Więc? sprawia, że ​​mecz kończy się za pierwszym razem? Jak nazywa się ta ... (nazwijmy to) właściwość wyrażenia regularnego?
Parziphal

1
@Parziphal ?postać sprawia, że ​​mecz jest leniwy (dopasowuje tyle razy, ile to możliwe). Pomyśl o wyrażeniach pasujących do wyrażenia regularnego aż do pierwszego średnika, a potem nie pójdzie dalej, ponieważ się poddaje (leniwy;))
derekantrican

5

nie jest to rozwiązanie wyrażenia regularnego, ale coś wystarczająco prostego do opisu problemu. Po prostu podziel swój ciąg i zdobądź pierwszy przedmiot z tablicy.

$str = "match everything until first ; blah ; blah end ";
$s = explode(";",$str,2);
print $s[0];

wynik

$ php test.php
match everything until first

5

Było to dla mnie bardzo pomocne, gdy próbowałem wymyślić, jak dopasować wszystkie znaki w tagu xml, w tym atrybuty. Wystąpił problem „dopasowuje wszystko do końca” z:

/<simpleChoice.*>/

ale udało się rozwiązać problem z:

/<simpleChoice[^>]*>/

po przeczytaniu tego postu. Dziękuje wszystkim.


1
Przekonałem się, że o wiele bardziej efektywne jest parsowanie (każdy język lub framework ma do tego swoje własne klasy) html / xml ze względu na format maszynowy, wyrażenia regularne są dla języka naturalnego.
Leon Fedotov,

1
Miły. Użyłem tego, aby naprawić dokumenty XML z błędami składniowymi w <!DOCTYPE>znaczniku. Ponieważ parser nie był w stanie sobie z tym poradzić.
Martin Schneider,

5

Spowoduje to dopasowanie do pierwszego wystąpienia tylko w każdym ciągu i zignoruje kolejne wystąpienia.

/^([^;]*);*/

3

"/^([^\/]*)\/$/" pracował dla mnie, aby uzyskać tylko najlepsze „foldery” z tablicy takiej jak:

a/   <- this
a/b/
c/   <- this
c/d/
/d/e/
f/   <- this

2

Naprawdę mi przykro, że nikt nie dał prawidłowej odpowiedzi ....

W wyrażeniach regularnych? sprawia, że ​​nie jest chciwy. Domyślnie regex będzie pasował jak najwięcej (zachłanny)

Po prostu dodać? i nie będzie chciwy i będzie pasował tak mało, jak to możliwe!

Powodzenia, mam nadzieję, że to pomaga.


3
Zależy to w dużej mierze od faktycznej implementacji wyrażenia regularnego i nie każda implementacja ma tryb nie chciwy.
karatedog

0

znalazłem to

/^[^,]*,/

działa dobrze.

„,” będący tutaj „ogranicznikiem”.

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.