Dosłowny sposób powiedzenia „szukaj do, X
ale nie uwzględniaj X
” to:
(?:(?!X).)*
gdzie X
może być dowolne wyrażenie regularne.
W twoim przypadku może to być przesada - tutaj najłatwiej byłoby
[^z]*
Dopasuje to wszystko oprócz z
i dlatego zatrzyma się tuż przed następnym z
.
Więc .*?quick[^z]*
będzie pasować The quick fox jumps over the la
.
Jednak na przykład, gdy masz więcej niż jedną prostą literę, na którą musisz zwrócić uwagę, (?:(?!X).)*
w grę wchodzi
(?:(?!lazy).)*
- dopasuj wszystko, aż do początku słowa lazy
.
To jest użycie asercji wyprzedzającej , a dokładniej negatywnej.
.*?quick(?:(?!lazy).)*
będzie pasować The quick fox jumps over the
.
Wyjaśnienie:
(?:
(?!lazy)
.
)*
Ponadto, podczas wyszukiwania słów kluczowych, możesz chcieć otoczyć je kotwicami granic słów: \bfox\b
dopasuje tylko całe słowo, fox
ale nie będzie zawierał listu foxy
.
Uwaga
Jeśli tekst, który ma zostać dopasowany, może również zawierać podziały wierszy, musisz ustawić opcję „kropka pasuje do wszystkich” w Twoim silniku wyrażeń regularnych. Zwykle można to osiągnąć, poprzedzając (?s)
wyrażenie regularne, ale to nie działa we wszystkich silnikach wyrażeń regularnych (zwłaszcza JavaScript).
Alternatywne rozwiązanie:
W wielu przypadkach można również użyć prostszego, bardziej czytelnego rozwiązania, które wykorzystuje leniwy kwantyfikator. Dodając a ?
do *
kwantyfikatora, spróbuje dopasować jak najmniej znaków z bieżącej pozycji:
.*?(?=(?:X)|$)
dopasuje dowolną liczbę znaków, zatrzymując się tuż przed X
(może to być dowolne wyrażenie regularne) lub na końcu ciągu (jeśli X
nie pasuje). Aby to zadziałało, może być konieczne ustawienie opcji „kropka pasuje do wszystkich”. (Uwaga: dodałem grupę bez przechwytywania X
, aby niezawodnie odizolować ją od naprzemienności)
grep
, ale ta odpowiedź działa.(?:...)
bez przechwytywania? Czy to działa((?!X).)*
?grep
do filtrowania żądań tylko jednej bazy danych z transformetu mysql bin w sql. Oto bestia:grep -Po "(?s)use database_to_keep(.*?)(?=^use)" mysql-bin.000045.sql > filtered.sql
Up
klawisz, ostatnie polecenie nie jest tym, którego użyłem:grep -Po "(?s)use database_to_keep(.*?)(?:(?!^use).)*" mysql-bin.000045.sql > filtered.sql
$
alternatywny zamienić.*?(?=X)
z.*?(?=X|$)
Składnia uprzedzona regex może pomóc Ci osiągnąć swój cel. Tak więc wyrażenie regularne dla twojego przykładu to
.*?quick.*?(?=z)
I ważne jest, aby zwrócić uwagę na
.*?
leniwe dopasowywanie przed(?=z)
lookahead: wyrażenie dopasowuje podłańcuch aż do pierwszego wystąpieniaz
litery.Oto przykładowy kod w języku C #:
const string text = "The quick red fox jumped over the lazy brown dogz"; string lazy = new Regex(".*?quick.*?(?=z)").Match(text).Value; Console.WriteLine(lazy); // The quick red fox jumped over the la string greedy = new Regex(".*?quick.*(?=z)").Match(text).Value; Console.WriteLine(greedy); // The quick red fox jumped over the lazy brown dog
źródło
Spróbuj tego
źródło