Nie wszystkie odmiany wyrażeń regularnych to umożliwiają. W jakim środowisku pracujesz? Jawa? Perl? .NETTO? Jakaś biblioteka wyrażeń regularnych C / C ++? RDBMS?
FrustratedWithFormsDesigner
8
Nie mówisz, czego chcesz, ale możesz po prostu odwrócić sens operacji „dopasuj”. To nie pomoże, jeśli próbujesz wyodrębnić niepasujące części, ale aby sprawdzić, czy nie ma wykluczonego ciągu, zadziała: if (!s.match(/red|green|blue/)) ... Uwaga: Wiem, że OP nie określa języka / struktury, więc powyższy przykład należy traktować jako ogólny przykład, a nie nakazowy.
tvanfosson
Odpowiedzi:
154
Jeśli chcesz się upewnić, że sznurek nie jest ani czerwony, ani zielony, ani niebieski, odpowiedź Caskey jest taka. Często jednak pożądane jest upewnienie się, że linia nie zawiera w żadnym miejscu koloru czerwonego, zielonego ani niebieskiego. W tym celu zakotwicz wyrażenie regularne za pomocą ^i uwzględnij .*w negatywnym wyglądzie:
^(?!.*(red|green|blue))
Załóżmy też, że chcesz wiersze zawierające słowo „silnik”, ale bez żadnego z tych kolorów:
^(?!.*(red|green|blue)).*engine
Możesz pomyśleć, że możesz uwzględnić to .*na początku wyrażenia regularnego:
^.*(?!red|green|blue)engine # Does not work
ale nie możesz. Musisz mieć oba wystąpienia .*, aby działało.
@caskey, Pełna odpowiedź to połączenie moje i twojego. Jeśli chcesz je połączyć, usunę moje.
Wayne Conrad
14
Ta odpowiedź byłaby o wiele bardziej przydatna, gdybyś ją trochę wyjaśnił. Na przykład: co oznacza „?” i "!" oznaczać? Dlaczego potrzebujesz grup przechwytywania?
Lii
To także poprawny Python.
Joe Mornin
właśnie użyłem tego z biblioteką regEx Delphi i działa tylko tak: ^ (?! red | green | blue). Dotyczy to również testowania w witrynie regex101.com . Czy powyższa literówka nie zawiera ^, czy faktycznie działa tak w Javie / Perl / Pythonie ..?
Peter
33
Dopasowywanie wszystkiego oprócz danych ciągów
Jeśli chcesz dopasować cały ciąg, w którym chcesz dopasować wszystko oprócz niektórych ciągów, możesz to zrobić w następujący sposób:
^(?!(red|green|blue)$).*$
Oznacza to, że rozpocznij dopasowanie od początku ciągu, w którym nie może zaczynać się i kończyć kolorem czerwonym, zielonym lub niebieskim, i dopasowywać wszystko inne do końca ciągu.
Możesz drastycznie zmniejszyć liczbę kroków, zamieniając [\ s \ S] na kropkę. Byłem bardzo zdezorientowany, dlaczego pozornie każdy inny przykład oddaje każde słowo z osobna. W ten sposób jest nieco więcej kroków regex, ale wymaga znacznie mniej przetwarzania końcowego.
Zatronium
3
ale to nie robi dopasowywania (sprawdzania poprawności tekstu), po prostu usuwa określony tekst podczas podstawiania.
Marek R
To rozwiązanie nie wyświetli ostatniego fragmentu tekstu po znanych słowach. Nie ma więc potrzeby porównywania prędkości, po prostu jest źle.
Wiktor Stribiżew
@ WiktorStribiżew naprawiono.
hlcs
10
Miałem to samo pytanie, proponowane rozwiązania prawie działały, ale miały jakiś problem. Ostatecznie wyrażenie regularne, którego użyłem, to:
^(?!red|green|blue).*
Przetestowałem to w Javascript i .NET.
. * nie powinno być umieszczane wewnątrz ujemnego lookahead w ten sposób: ^ (?!. * red | green | blue) albo spowodowałoby to, że pierwszy element zachowywałby się inaczej niż reszta (tj. „inny czerwony” nie zostałby dopasowany, podczas gdy " inny zielony ”)
Dopasowanie dowolnego tekstu poza tymi, które pasują do wzorca, zwykle uzyskuje się przez podzielenie ciągu za pomocą wzorca wyrażenia regularnego .
Przykłady :
do#- Regex.Split(text, @"red|green|blue")lub, aby pozbyć się pustych wartości Regex.Split(text, @"red|green|blue").Where(x => !string.IsNullOrEmpty(x))(patrz demo )
vb.net- Regex.Split(text, "red|green|blue")lub, aby usunąć puste elementy Regex.Split(text, "red|green|blue").Where(Function(s) Not String.IsNullOrWhitespace(s))(zobacz demo lub to demo, w którym obsługiwane jest LINQ)
javascript- text.split(/red|green|blue/)(nie ma potrzeby używania gtutaj modyfikatora!) (aby pozbyć się pustych wartości, użyj text.split(/red|green|blue/).filter(Boolean)), zobacz demo
Jawa- text.split("red|green|blue")lub - aby zachować wszystkie końcowe puste elementy - użyj text.split("red|green|blue", -1)lub, aby usunąć wszystkie puste elementy, użyj więcej kodu, aby je usunąć (zobacz demo )
groovy- Podobnie jak w Javie,, text.split(/red|green|blue/)aby uzyskać użycie wszystkich elementów końcowych text.split(/red|green|blue/, -1)i usunąć wszystkie puste elementy text.split(/red|green|blue/).findAll {it != ""})(patrz demo )
kotlin- text.split(Regex("red|green|blue"))lub, aby usunąć puste elementy, użyj text.split(Regex("red|green|blue")).filter{ !it.isBlank() }, zobacz demo
scala- text.split("red|green|blue")lub aby zachować wszystkie końcowe puste elementy, użyj text.split("red|green|blue", -1)i, aby usunąć wszystkie puste elementy, użyj text.split("red|green|blue").filter(_.nonEmpty)(zobacz demo )
rubin- text.split(/red|green|blue/), aby pozbyć się pustych wartości, użyj .split(/red|green|blue/).reject(&:empty?)(i aby uzyskać zarówno początkowe, jak i końcowe puste elementy, użyj -1jako drugiego argumentu, .split(/red|green|blue/, -1)) (patrz demo )
perl- my @result1 = split /red|green|blue/, $text;lub ze wszystkimi końcowymi pustymi pozycjami my @result2 = split /red|green|blue/, $text, -1;, lub bez żadnych pustych pozycji my @result3 = grep { /\S/ } split /red|green|blue/, $text;(patrz demo )
php- preg_split('~red|green|blue~', $text)lub preg_split('~red|green|blue~', $text, -1, PREG_SPLIT_NO_EMPTY)aby nie wyświetlać żadnych pustych pozycji (patrz demo )
udać się- Użyj regexp.MustCompile("red|green|blue").Split(text, -1), a jeśli chcesz usunąć puste elementy, użyj tego kodu . Zobacz demo Go .
UWAGA : Jeśli wzorce zawierają grupy przechwytywania , funkcje / metody podziału wyrażeń regularnych mogą zachowywać się inaczej, również w zależności od dodatkowych opcji. W takim przypadku należy zapoznać się z odpowiednią dokumentacją metody podziału.
if (!s.match(/red|green|blue/)) ...
Uwaga: Wiem, że OP nie określa języka / struktury, więc powyższy przykład należy traktować jako ogólny przykład, a nie nakazowy.Odpowiedzi:
Jeśli chcesz się upewnić, że sznurek nie jest ani czerwony, ani zielony, ani niebieski, odpowiedź Caskey jest taka. Często jednak pożądane jest upewnienie się, że linia nie zawiera w żadnym miejscu koloru czerwonego, zielonego ani niebieskiego. W tym celu zakotwicz wyrażenie regularne za pomocą
^
i uwzględnij.*
w negatywnym wyglądzie:Załóżmy też, że chcesz wiersze zawierające słowo „silnik”, ale bez żadnego z tych kolorów:
Możesz pomyśleć, że możesz uwzględnić to
.*
na początku wyrażenia regularnego:ale nie możesz. Musisz mieć oba wystąpienia
.*
, aby działało.źródło
Zależy od języka, ale generalnie są twierdzenia negatywne, które można umieścić w ten sposób:
(Dzięki za poprawkę składni, powyższe dotyczy poprawnych Java i Perl, YMMV)
źródło
Dopasowywanie wszystkiego oprócz danych ciągów
Jeśli chcesz dopasować cały ciąg, w którym chcesz dopasować wszystko oprócz niektórych ciągów, możesz to zrobić w następujący sposób:
^(?!(red|green|blue)$).*$
Oznacza to, że rozpocznij dopasowanie od początku ciągu, w którym nie może zaczynać się i kończyć kolorem czerwonym, zielonym lub niebieskim, i dopasowywać wszystko inne do końca ciągu.
Możesz spróbować tutaj: https://regex101.com/r/rMbYHz/2
Zauważ, że działa to tylko z silnikami regex, które obsługują negatywne lookahead .
źródło
Nie potrzebujesz negatywnego spojrzenia w przód. Oto działający przykład:
Opis:
[\s\S]
- dopasuj dowolny znak*
- mecz od 0 do nieograniczonej liczby z poprzedniej grupy?
- dopasuj jak najmniej(red|green|blue|)
- dopasuj jedno z tych słów lub nicg
- powtórz wzórPrzykład:
whiteredwhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredgreenbluewhiteredwhiteredwhiteredwhiteredwhiteredwhiteredgreenbluewhiteredwhiteredwhiteredwhiteredwhiteredredgreenredgreenredgreenredgreenredgreenbluewhiteredbluewhiteredbluewhiteredbluewhiteredbluewhiteredwhite
Będzie:
whitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhitewhite
Sprawdź to:
regex101.com
źródło
Miałem to samo pytanie, proponowane rozwiązania prawie działały, ale miały jakiś problem. Ostatecznie wyrażenie regularne, którego użyłem, to:
Przetestowałem to w Javascript i .NET.
. * nie powinno być umieszczane wewnątrz ujemnego lookahead w ten sposób: ^ (?!. * red | green | blue) albo spowodowałoby to, że pierwszy element zachowywałby się inaczej niż reszta (tj. „inny czerwony” nie zostałby dopasowany, podczas gdy " inny zielony ”)
źródło
Dopasowanie dowolnego tekstu poza tymi, które pasują do wzorca, zwykle uzyskuje się przez podzielenie ciągu za pomocą wzorca wyrażenia regularnego .
Przykłady :
Regex.Split(text, @"red|green|blue")
lub, aby pozbyć się pustych wartościRegex.Split(text, @"red|green|blue").Where(x => !string.IsNullOrEmpty(x))
(patrz demo )Regex.Split(text, "red|green|blue")
lub, aby usunąć puste elementyRegex.Split(text, "red|green|blue").Where(Function(s) Not String.IsNullOrWhitespace(s))
(zobacz demo lub to demo, w którym obsługiwane jest LINQ)text.split(/red|green|blue/)
(nie ma potrzeby używaniag
tutaj modyfikatora!) (aby pozbyć się pustych wartości, użyjtext.split(/red|green|blue/).filter(Boolean)
), zobacz demotext.split("red|green|blue")
lub - aby zachować wszystkie końcowe puste elementy - użyjtext.split("red|green|blue", -1)
lub, aby usunąć wszystkie puste elementy, użyj więcej kodu, aby je usunąć (zobacz demo )text.split(/red|green|blue/)
aby uzyskać użycie wszystkich elementów końcowychtext.split(/red|green|blue/, -1)
i usunąć wszystkie puste elementytext.split(/red|green|blue/).findAll {it != ""})
(patrz demo )text.split(Regex("red|green|blue"))
lub, aby usunąć puste elementy, użyjtext.split(Regex("red|green|blue")).filter{ !it.isBlank() }
, zobacz demotext.split("red|green|blue")
lub aby zachować wszystkie końcowe puste elementy, użyjtext.split("red|green|blue", -1)
i, aby usunąć wszystkie puste elementy, użyjtext.split("red|green|blue").filter(_.nonEmpty)
(zobacz demo )text.split(/red|green|blue/)
, aby pozbyć się pustych wartości, użyj.split(/red|green|blue/).reject(&:empty?)
(i aby uzyskać zarówno początkowe, jak i końcowe puste elementy, użyj-1
jako drugiego argumentu,.split(/red|green|blue/, -1)
) (patrz demo )my @result1 = split /red|green|blue/, $text;
lub ze wszystkimi końcowymi pustymi pozycjamimy @result2 = split /red|green|blue/, $text, -1;
, lub bez żadnych pustych pozycjimy @result3 = grep { /\S/ } split /red|green|blue/, $text;
(patrz demo )preg_split('~red|green|blue~', $text)
lubpreg_split('~red|green|blue~', $text, -1, PREG_SPLIT_NO_EMPTY)
aby nie wyświetlać żadnych pustych pozycji (patrz demo )re.split(r'red|green|blue', text)
lub, aby usunąć puste elementy,list(filter(None, re.split(r'red|green|blue', text)))
(zobacz demo )regexp.MustCompile("red|green|blue").Split(text, -1)
, a jeśli chcesz usunąć puste elementy, użyj tego kodu . Zobacz demo Go .UWAGA : Jeśli wzorce zawierają grupy przechwytywania , funkcje / metody podziału wyrażeń regularnych mogą zachowywać się inaczej, również w zależności od dodatkowych opcji. W takim przypadku należy zapoznać się z odpowiednią dokumentacją metody podziału.
źródło
Wszystkie oprócz słowa „czerwony”
Wszystkie oprócz słowa „czerwony”
źródło