Znalazłem bardzo podobne posty, ale nie mogę znaleźć tutaj mojego wyrażenia regularnego.
Próbuję napisać wyrażenie regularne, które zwraca ciąg, który znajduje się między dwoma innymi ciągami. Na przykład: chcę uzyskać ciąg, który znajduje się między ciągami „krowa” i „mleko”.
Moja krowa zawsze daje mleko
wróci
„zawsze daje”
Oto wyrażenie, które stworzyłem do tej pory:
(?=cow).*(?=milk)
Jednak zwraca to ciąg „krowa zawsze daje”.
javascript
regex
string
phil
źródło
źródło
Odpowiedzi:
Lookahead (ta
(?=
część) nie zużywa żadnych danych wejściowych. Jest to asercja o zerowej szerokości (podobnie jak sprawdzanie granic i lookbehinds).Chcesz tutaj regularne zapałki, aby skonsumować
cow
porcję. Aby uchwycić część pomiędzy, użyj grupy przechwytywania (po prostu umieść fragment wzorca, który chcesz uchwycić, w nawiasach):W ogóle nie są potrzebne żadne lookahead.
źródło
matched[1]
, a nie cały dopasowany tekstmatched[0]
.([\s\S]*?)
zamiast(.*?)
.Najbardziej kompletnym rozwiązaniem, które będzie działać w zdecydowanej większości przypadków, jest użycie grupy przechwytywania z leniwym wzorem dopasowywania kropek . Jednak kropka
.
w wyrażeniu regularnym JavaScript nie pasuje do znaków końca wiersza, więc to, co zadziała w 100%, to konstrukcja[^]
lub[\s\S]
/[\d\D]
/[\w\W]
.ECMAScript 2018 i nowsze kompatybilne rozwiązanie
W środowisku JavaScript podtrzymujących ECMAScript 2018 ,
s
modyfikatora umożliwia.
dopasowanie wszystkich char tym włamaniowych linii znaków i regex wsporniki silnika lookbehinds o zmiennej długości. Możesz więc użyć wyrażenia regularnego, takiego jakW obu przypadkach bieżąca pozycja jest sprawdzana za
cow
pomocą 1/0 lub więcej białych znaków pocow
, a następnie dowolne 0+ znaków tak mało, jak to możliwe, jest dopasowywane i konsumowane (= dodawane do wartości dopasowania), a następniemilk
sprawdzane pod kątem (z dowolnymi 1/0 lub więcej białych znaków przed tym podciągiem).Scenariusz 1: wejście jednoliniowe
Ten i wszystkie inne poniższe scenariusze są obsługiwane przez wszystkie środowiska JavaScript. Zobacz przykłady użycia na dole odpowiedzi.
cow
znaleziono, następnie miejsce, wtedy każdy 0+ znaki inne niż linia przerwy znaków, tak mało jak to możliwe, jak*?
to leniwa kwantyfikator, są ujęte w grupy 1, a następnie z przestrzenimilk
muszą przestrzegać (oraz są dopasowane i spożywane zbyt ).Scenariusz 2: wejście wieloliniowe
Tutaj
cow
i spacja są najpierw dopasowywane, następnie dowolne 0+ znaków, jak najmniej, jest dopasowywanych i przechwytywanych do grupy 1, a następnie spacja zmilk
jest dopasowywana.Scenariusz 3: Pokrywające się mecze
Jeśli masz taki ciąg
>>>15 text>>>67 text2>>>
i chcesz uzyskać 2 dopasowania pomiędzy>>>
+number
+whitespace
i>>>
, nie możesz użyć,/>>>\d+\s(.*?)>>>/g
ponieważ spowoduje to znalezienie tylko 1 dopasowania, ponieważ>>>
poprzednia67
jest już zużyta po znalezieniu pierwszego dopasowania. Możesz użyć pozytywnego lookahead, aby sprawdzić obecność tekstu bez faktycznego „pożerania” go (tj. Dołączania do dopasowania):Zobacz demo regex Internecie plonowanie
text1
itext2
jako Grupa 1 znalezionych zawartość.Zobacz także Jak uzyskać wszystkie możliwe nakładające się dopasowania dla ciągu .
Uwagi dotyczące wydajności
Leniwy wzorzec dopasowania kropek (
.*?
) wewnątrz wzorców regex może spowolnić wykonywanie skryptu, jeśli podano bardzo długie dane wejściowe. W wielu przypadkach technika rozwijania pętli pomaga w większym stopniu. Próbując złapać wszystko pomiędzycow
imilk
z"Their\ncow\ngives\nmore\nmilk"
, widzimy, że musimy dopasować wszystkie linie, które nie zaczynają się odmilk
, więc zamiastcow\n([\s\S]*?)\nmilk
możemy użyć:Zobacz demo wyrażeń regularnych (jeśli istnieje
\r\n
, użyj/cow\r?\n(.*(?:\r?\n(?!milk$).*)*)\r?\nmilk/gm
). W przypadku tego małego ciągu testowego wzrost wydajności jest pomijalny, ale w przypadku bardzo dużego tekstu poczujesz różnicę (zwłaszcza jeśli linie są długie, a znaki końca linii nie są zbyt liczne).źródło
Oto wyrażenie regularne, które przechwytuje to, co jest między krową a mlekiem (bez spacji na początku / końcu):
Przykład: http://jsfiddle.net/entropo/tkP74/
źródło
.*
.*
graniemNaprawdę nie ma potrzeby patrzenia w przyszłość.
źródło
Wybrana odpowiedź nie działa dla mnie ... hmm ...
Wystarczy dodać spację po krowie i / lub przed mlekiem, aby usunąć spacje z „zawsze daje”
źródło
?<=
nie jest obsługiwana w JavaScript.Udało mi się uzyskać to, czego potrzebowałem, korzystając z rozwiązania Martinho Fernandesa poniżej. Kod to:
Zauważysz, że ostrzegam zmienną testRE jako tablicę. Dzieje się tak, ponieważ z jakiegoś powodu testRE zwraca jako tablicę. Wynik z:
Zmiany w:
źródło
Po prostu użyj następującego wyrażenia regularnego:
źródło
?<=
nie jest obsługiwana w JavaScript. Byłby to jednak sposób na zrobienie tego.Uważam, że regex jest żmudny i czasochłonny, biorąc pod uwagę składnię. Ponieważ używasz już javascript, łatwiej jest wykonać następujące czynności bez wyrażenia regularnego:
źródło
Jeśli dane znajdują się w wielu wierszach, może być konieczne użycie następującego,
Przykład Regex 101
źródło
Metoda match () przeszukuje ciąg znaków pod kątem dopasowania i zwraca obiekt Array.
źródło
Zadanie
Wyodrębnij podciąg między dwoma ciągami (z wyłączeniem tych dwóch ciągów)
Rozwiązanie
źródło