Przyjmować tego wyrażenia regularnego: /^[^abc]/
. Spowoduje to dopasowanie dowolnego znaku na początku łańcucha, z wyjątkiem a, b lub c.
Jeśli dodasz *
po nim - /^[^abc]*/
- wyrażenie regularne będzie dodawać każdy kolejny znak do wyniku, dopóki nie spotka się z a
, lub b
, lub c
.
Na przykład w przypadku ciągu źródłowego "qwerty qwerty whatever abc hello"
wyrażenie będzie pasować do"qwerty qwerty wh"
.
Ale co, jeśli chcę, aby pasował do niego ciąg "qwerty qwerty whatever "
... Innymi słowy, jak mogę dopasować wszystko do dokładnej sekwencji (ale nie w tym) "abc"
?
match but not including
?"qwerty qwerty whatever "
- nie licząc „abc”. Innymi słowy, nie chcę, aby wynikowe dopasowanie było"qwerty qwerty whatever abc"
.do string.split('abc')[0]
. Z pewnością nie jest to oficjalna odpowiedź na ten problem, ale uważam, że jest to prostsze niż regex.Odpowiedzi:
Nie określiłeś, jakiego smaku wyrażenia regularnego używasz, ale zadziała to w jednym z najbardziej popularnych, które można uznać za „kompletne”.
Jak to działa
Ta
.+?
część to niechciana wersja.+
(jednego lub więcej czegokolwiek). Kiedy używamy.+
, silnik zasadniczo wszystko pasuje. Następnie, jeśli w wyrażeniu regularnym jest coś jeszcze, cofnie się w krokach, próbując dopasować następną część. Jest to zachłanne zachowanie, co oznacza jak najwięcej do zaspokojenia .Podczas używania
.+?
zamiast dopasowywać wszystkie naraz i wracać do innych warunków (jeśli występują), silnik będzie dopasowywał kolejne znaki krok po kroku, dopóki kolejna część wyrażenia regularnego nie zostanie dopasowana (ponownie, jeśli w ogóle). To jest niechciane , co oznacza dopasowanie najmniejszej możliwej do zaspokojenia .Następnie mamy stwierdzenie o zerowej szerokości i rozejrzyj się . Ta zgrupowana konstrukcja pasuje do jej zawartości, ale nie jest liczona jako dopasowane znaki ( szerokość zero ). Zwraca tylko, jeśli jest to dopasowanie, czy nie ( twierdzenie ).
(?=
{contents}
)
Zatem, innymi słowy, wyrażenie regularne
/.+?(?=abc)/
oznacza:źródło
.+?
i.*
?+
oznacza 1 lub więcej, gdzie*
oznacza 0 lub więcej. Włączenie / wyłączenie?
spowoduje, że będzie on chciwy lub niechciany.^(?:(?!abc)(?!def).)*
łańcucha, aby wykluczyć wzorce, których nie chcesz i nadal pobierze wszystko w razie potrzeby, nawet jeśli wzorzec nie istniejeJeśli chcesz uchwycić wszystko do „abc”:
Wyjaśnienie:
( )
uchwycić wyraz wewnątrz nawiasów dostępu użyciu$1
,$2
itp^
dopasuj początek linii.*
dopasuj wszystko,?
niechciwie (dopasuj minimalną wymaganą liczbę znaków) - [1][1] Powodem, dla którego jest to potrzebne, jest to, że inaczej, w następującym ciągu:
domyślnie wyrażenia regularne są zachłanne , co oznacza, że będą pasować jak najwięcej. Dlatego
/^.*abc/
pasowałoby „cokolwiek cokolwiek abc coś”. Dodanie niepochodnego kwantyfikatora?
powoduje, że regex pasuje tylko „cokolwiek, co”.źródło
sed
wydaje się nie obsługiwać chciwego dopasowywania, ani nie obsługuje rozglądania się ((?=...)
). Co jeszcze mogę zrobić? Przykładowe polecenie:echo "ONE: two,three, FOUR FIVE, six,seven" | sed -n -r "s/^ONE: (.+?), .*/\1/p"
zwracatwo,three, FOUR FIVE
, ale spodziewam siętwo,three
...two
, a nietwo,three
.Jak zauważyli @Jared Ng i @Issun, klucz do rozwiązania tego rodzaju RegEx, np. „Dopasowywanie wszystkiego do określonego słowa lub podłańcucha” lub „dopasowanie wszystkiego po określonym słowie lub podłańcuchu” nazywa się „patrzeniem” na twierdzenia o zerowej długości . Przeczytaj więcej o nich tutaj.
W twoim konkretnym przypadku można to rozwiązać pozytywnie:
.+?(?=abc)
Obraz jest wart tysiąca słów. Zobacz szczegółowe wyjaśnienie na zrzucie ekranu.
źródło
.+?(?=abc)
wyrażenie regularne z możliwością kopiowania jest warte więcej.To, czego potrzebujesz, to rozejrzyj się wokół takiego stwierdzenia
.+? (?=abc)
.Zobacz: asercje Lookahead i Lookbehind o zerowej długości
Pamiętaj, że
[abc]
to nie to samo, coabc
. W nawiasach nie jest to ciąg znaków - każda postać jest tylko jedną z możliwości. Poza nawiasami staje się ciągiem.źródło
Dla wyrażeń regularnych w Javie i wierzę również w większość silników wyrażeń regularnych, jeśli chcesz dołączyć ostatnią część, to zadziała:
Na przykład w tym wierszu:
zaznacz wszystkie znaki do „abc”, a także włącz abc
przy użyciu naszego wyrażenia regularnego wynikiem będzie:
I have this very nice senabc
Sprawdź to: https://regex101.com/r/mX51ru/1
źródło
Zakończyłem to pytanie dotyczące przepełnienia stosu, szukając pomocy w rozwiązaniu mojego problemu, ale nie znalazłem rozwiązania :(
Musiałem więc improwizować ... po pewnym czasie udało mi się dotrzeć do wyrażenia regularnego, którego potrzebowałem:
Jak widać, potrzebowałem do jednego folderu przed folderem „grp-bps”, bez ostatniej kreski. Wymagany był przynajmniej jeden folder po folderze „grp-bps”.
Edytować
Wersja tekstowa do kopiuj-wklej (zmień „grp-bps” na tekst):
źródło
Będzie to miało sens w przypadku wyrażenia regularnego.
Tutaj możemy uzyskać dokładnie to słowo, które należy do podwójnych cudzysłowów. Na przykład jeśli naszym wyszukiwanym tekstem jest,
To jest przykład słów „podwójnie cytowanych”
wtedy otrzymamy „podwójne cytowanie” z tego zdania.
źródło
"
, co wydaje mi się nieistotne dla pytania.W pythonie:
.+?(?=abc)
działa w przypadku pojedynczej linii.[^]+?(?=abc)
nie działa, ponieważ python nie rozpoznaje [^] jako poprawnego wyrażenia regularnego. Aby dopasowanie wieloliniowe działało, musisz użyć opcji re.DOTALL, na przykład:źródło
Uważam, że potrzebujesz podwyrażeń. Jeśli dobrze pamiętam, możesz użyć normalnego
()
nawiasów podwyrażeń.Ta część pochodzi z podręcznika grep:
Zrób coś takiego,
^[^(abc)]
powinno załatwić sprawę.źródło
Te
$
znaki na końcu łańcucha, więc coś jak to powinno działać:[[^abc]*]$
gdzie szukasz czegoś nie kończącego się w każdej iteracjiabc
, ale musiałby to być na końcuRównież jeśli używasz języka skryptowego z wyrażeniem regularnym (takim jak php lub js), mają one funkcję wyszukiwania, która zatrzymuje się, gdy po raz pierwszy napotka wzorzec (i możesz określić początek od lewej lub początek od prawej lub za pomocą php, możesz wykonać implode, aby wykonać kopię lustrzaną łańcucha).
źródło
Spróbuj tego
Zapytanie:
wynik :
źródło