Rozważmy następujące wyrażenie regularne, gdzie X
jest dowolne wyrażenie regularne.
X{n}|X{m}
To wyrażenie regularne sprawdzałoby , czy X
występuje dokładnie n
lub m
razy.
Czy istnieje kwantyfikator wyrażeń regularnych, który może X
dokładnie sprawdzać wystąpienie n
lub m
czas?
X
jest najlepszy można dostać za ogólnym
,n
.(X)\1{n-1}(?:\1{m-n-1})
. Wiem, że to pasujeX
przynajmniej raz, ale żeby zacząć, wypróbuj tę prostą rzecz, a następnie udoskonal, używając zamiast tego lookaheads lub lookbinds(X)
.Odpowiedzi:
Nie ma jednego kwantyfikatora, który oznacza „dokładnie m lub n razy”. Sposób, w jaki to robisz, jest w porządku.
Alternatywą jest:
gdzie
m < n
ik
jest wartościąn-m
.źródło
Oto pełna lista kwantyfikatorów (patrz http://www.regular-expressions.info/reference.html ):
?
,??
- 0 lub 1 wystąpień (??
jest leniwy,?
jest chciwy)*
,*?
- dowolna liczba wystąpień+
,+?
- co najmniej jedno wystąpienie{n}
- dokładnien
occurences{n,m}
-n
dom
zdarzeń włącznie{n,m}?
-n
nam
wypadki, leniwy{n,}
,{n,}?
- co najmniejn
występowaniaAby uzyskać „dokładnie N lub M”, musisz dwukrotnie napisać wyrażone ilościowo wyrażenie regularne, chyba że m, n są specjalne:
X{n,m}
Jeślim = n+1
(?:X{n}){1,2}
Jeślim = 2n
źródło
?:
potrzebne wm = 2n
przykładzie if ? Wydaje mi się, że bez niego działa dobrze.?:
, grupa stanie się grupą przechwytującą. Oprócz tego, że silnik regex zapamiętuje rzeczy, których nie musi, jeśli masz grupy przechwytujące po tej, ich identyfikatory ulegną zmianie. Jeśli używasz wyrażenia regularnego do zamiany, będziesz musiał dostosować zamianę.Nie, nie ma takiego kwantyfikatora. Ale zrestrukturyzowałbym to,
/X{m}(X{m-n})?/
aby zapobiec problemom z wycofywaniem się .źródło
TLDR;
(?<=[^x]|^)(x{n}|x{m})(?:[^x]|$)
Wygląda na to, że chcesz „xn razy” lub „xm razy”, myślę, że dosłowne tłumaczenie wyrażenia regularnego wyglądałoby
(x{n}|x{m}).
tak: https://regex101.com/r/vH7yL5/1lub w przypadku, gdy możesz mieć sekwencję większą niż m „x” s (zakładając m> n), możesz dodać „po braku” x ”i„ po którym nie ma „x”, co oznacza
[^x](x{n}|x{m})[^x]
, że załóż, że za tobą i za tobą zawsze jest znak "x". Jak widać tutaj: https://regex101.com/r/bB2vH2/1możesz to zmienić na
(?:[^x]|^)(x{n}|x{m})(?:[^x]|$)
, tłumacząc na „następujący po braku 'x' lub następujący po początku linii” i „po którym następuje brak 'x' lub po którym następuje koniec linii”. Ale nadal nie będzie pasował do dwóch sekwencji z tylko jednym znakiem między nimi (ponieważ pierwsze dopasowanie wymagałoby znaku po, a drugie znaku wcześniej), jak widać tutaj: https://regex101.com/r/ oC5oJ4 / 1Na koniec, aby dopasować odległe dopasowanie o jeden znak, możesz dodać pozytywne spojrzenie w przód (? =) Na „brak 'x' po” lub pozytywne spojrzenie w tył (? <=) Na „brak 'x” przed ”, w ten sposób: https://regex101.com/r/mC4uX3/1
W ten sposób dopasujesz tylko dokładną liczbę „x”, jaką chcesz.
źródło
Patrząc na odpowiedź Enhardened, stwierdzają, że ich przedostatnie wyrażenie nie będzie pasować do sekwencji z tylko jednym znakiem między nimi. Istnieje łatwy sposób na naprawienie tego problemu bez użycia patrzenia w przód / w tył, a jest to zastąpienie znaku początku / końca znakiem granicy. Pozwala to dopasować do granic słów, które obejmują początek / koniec. W związku z tym odpowiednie wyrażenie powinno brzmieć:
(?:[^x]|\b)(x{n}|x{m})(?:[^x]|\b)
Jak widać tutaj: https://regex101.com/r/oC5oJ4/2 .
źródło
Bardzo stary post, ale chciałbym wnieść coś, co może być pomocne. Wypróbowałem to dokładnie w sposób opisany w pytaniu i działa, ale jest haczyk: kolejność ilości ma znaczenie. Rozważ to:
Spowoduje to wyświetlenie wszystkich wystąpień szesnastkowych kodów kolorów (mają one długość 3 lub 6 cyfr). Ale kiedy odwracam to w ten sposób
znajdzie tylko 3-cyfrowe lub pierwsze 3 cyfry 6-cyfrowych. Ma to sens i profesjonalista firmy Regex może to od razu zauważyć, ale dla wielu może to być dziwne zachowanie. Istnieją pewne zaawansowane funkcje Regex, które mogą uniknąć tej pułapki niezależnie od kolejności, ale nie wszyscy są po kolana w wzorach Regex.
źródło