2010-03-08 10 views
60

Wiem, że poniższe wyrażenie dopasuje "czerwony", "zielony" lub "niebieski".Dopasuj wszystko z wyjątkiem określonych ciągów znaków

red|green|blue 

Czy istnieje prosty sposób dzięki czemu pasuje do wszystkiego wyjątkiem kilku określonych ciągów?

+1

Nie wszystkie smaki wyrażeń regularnych mogą to zrobić. W jakim środowisku pracujesz? Jawa? Perl? .NETTO? Niektóre biblioteki regex C/C++? RDBMS? – FrustratedWithFormsDesigner

+5

Nie mówisz tego, czego chcesz, ale możesz po prostu odwrócić sens operacji "dopasowywania". To nie pomoże, jeśli próbujesz wyodrębnić niepasujące części, ale aby sprawdzić, czy wykluczony ciąg znaków nie jest obecny, działałoby: 'if (! S.match (/ red | green | blue /)) ... 'Uwaga: Wiem, że OP nie określa, jaki język/ramy, więc poprzedni powinien być uważany za ogólny przykład, a nie nakazowy. – tvanfosson

Odpowiedz

28

zależy od języka, ale są na ogół ujemne twierdzenia można umieścić w taki sposób:

(?!red|green|blue) 

(Dzięki za poprawki składni, powyższe jest ważny Java i Perl, YMMV)

+2

Masz na myśli '(?! Red | green | blue)'. –

+1

@caskey, pełna odpowiedź to połączenie mojego i twojego. Jeśli chcesz je scalić, usunę moje. –

+4

Ta odpowiedź byłaby o wiele bardziej przydatna, wyjaśniłeś to trochę. Na przykład: co robi "?" i "!" oznaczać? Dlaczego potrzebujesz grup przechwytujących? – Lii

87

Jeśli chcesz się upewnić, że ciąg nie jest czerwony, zielony ani niebieski, odpowiedź caskey jest to. Jednak często pożądane jest upewnienie się, że linia nie zawiera nigdzie czerwieni, zieleni ani niebieskiego. Do tego zakotwiczyć wyrażenie regularne z ^ i obejmują .* w negatywnym uprzedzona:

^(?!.*(red|green|blue)) 

Również załóżmy, że chcesz wiersze zawierające słowo „silnika”, ale bez żadnego z tych kolorów:

^(?!.*(red|green|blue)).*engine 

można by pomyśleć można czynnik .* szefa wyrażenia regularnego:

^.*(?!red|green|blue)engine  # Does not work 

ale można nie. Aby działał, musisz mieć oba wystąpienia: .*.

+1

@Russ Dziękuję za wskazanie błędu. Edytowałem odpowiedź. Naprawiłem to za pomocą nawiasów, ale twoja poprawka z dodatkowymi kopiami '. *' Jest również dobra. Jednak nie jestem przekonany, że koniec. * Jest potrzebny. –

+0

końcowy. * Nie jest potrzebny, jeśli chcesz po prostu sprawdzić boolean dla dopasowania. Jeśli jednak chcesz, aby tekst w pełni pasował, potrzebujesz go. Również ... twoje nowe rozwiązanie jest ładne i czyste. Dzięki! – Russ

5

Miałem to samo pytanie, proponowane rozwiązania prawie działały, ale miały pewne problemy. Na końcu używane przeze mnie wyrażenie regularne to:

^(?!red|green|blue).* 

Testowałem to w JavaScript i .NET.

. * Nie powinno być umieszczane wewnątrz ujemnej strony w przód:^(?!. * Czerwony | zielony | niebieski) lub może sprawić, że pierwszy element będzie się różnił od reszty (tzn. "Inny" nie będzie być dopasowanym, gdy "innygreen" będzie)

15

Nie potrzebujesz negatywnej uprzedniej wcześniejszej.Jest przykładem pracy:

/([\s\S]*?)(red|green|blue)/g 

Opis:

  • [\s\S] - dowolny znak
  • * - mecz z 0 do nieograniczonej od poprzedniej grupy
  • ? - mecz możliwie jak najmniej
  • (red|green|blue) - dopasuj jedno z tych słów
  • g - powtarzacie

Przykład:

redwhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredwhiteredwhiteredwhiteredwhiteredwhiteredgreenbluewhiteredwhiteredwhiteredwhiteredwhiteredredgreenredgreenredgreenredgreenredgreenbluewhiteredbluewhiteredbluewhiteredbluewhiteredbluewhitered

będą:

whitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhite

testu to: regex101.com

Takes 1155 kroków, ale jeśli ktoś może improv e będę doceniony.

+1

Ta odpowiedź byłaby lepsza, gdybyś wyjaśnił, jak działa ta patten. – Lii

+0

@Lii Nie wiem, co w tym wzorze należy wyjaśnić. To podstawowe wyrażenie regularne. – hlcs

+4

Możesz drastycznie zmniejszyć liczbę kroków, zamieniając [\ s \ S] na kropkę. Byłem bardzo zdezorientowany, dlaczego pozornie każdy inny przykład uchwycił każde słowo indywidualnie. W ten sposób jest nieco więcej kroków do wyrażenia regularnego, ale wymaga znacznie mniejszego przetwarzania końcowego. – Zatronium

5

Dopasowane bynajmniej danych napisów

Jeśli chcesz dopasować cały ciąg, w którym chcesz, aby dopasować wszystko, ale pewnych ciągów można zrobić to tak:

^(?!(red|green|blue)$).*$

mówi Ten, początek dopasowanie od początku łańcucha, w którym nie może się zaczynać i kończyć czerwonym, zielonym lub niebieskim i pasuje do wszystkiego na końcu ciągu.

Można spróbować tu: https://regex101.com/r/rMbYHz/2

Zauważ, że to działa tylko z silnikami regex, które obsługują negative lookahead.

Powiązane problemy