Sprawdzanie poprawności adresów IPv4 za pomocą wyrażenia regularnego

90

Próbowałem uzyskać wydajne wyrażenie regularne do walidacji IPv4, ale bez powodzenia. Wydawało się, że w pewnym momencie miałem to z (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}, ale daje dziwne wyniki:

$ grep --version
grep (GNU grep) 2.7
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.1.1
192.168.1.1
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.1.255
192.168.1.255
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.255.255
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.1.2555
192.168.1.2555

Poszukałem, aby sprawdzić, czy już o to pytano i na które udzielono odpowiedzi, ale inne odpowiedzi wydają się po prostu pokazywać, jak określić 4 grupy 1-3 liczb, lub nie działają dla mnie.

Matthieu Cartier
źródło
12
Nie zapominaj, że A, AB i ABC to prawidłowe formy adresu IP, podobnie jak ABCD Seriously. Spróbuj ping 2130706433i ping 127.1chichot.
dty
1
Mój wariant online regexr.com/39hqf
Sllouyssgort

Odpowiedzi:

97

Masz już działającą odpowiedź, ale na wypadek, gdybyś był ciekawy, co było nie tak z twoim pierwotnym podejściem, odpowiedzią jest, że potrzebujesz nawiasów wokół swojej zmiany, w przeciwnym razie (\.|$)jest wymagana tylko wtedy, gdy liczba jest mniejsza niż 200.

'\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b'
    ^                                    ^
Mark Byers
źródło
25
wydaje się, że potwierdza to również takie rzeczy, jak192.168.1.1.1
cwd
2
Powinien być \b((?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:(?<!\.)\b|\.)){4}:; tzn. więc kończy się granicą słowa, a nie końcem wiersza? Dodatkowo tutaj zaznaczyłem grupy bez przechwytywania, aby uniknąć niechcianych dopasowań podrzędnych. NB: To nadal nie uwzględnia komentarza @ dty, ponieważ nie jestem zaznajomiony z tą formą adresu IP; chociaż ma rację, że wydaje się ważny.
JohnLBevan
Zamiast tego możesz spróbować tego: ((1? \ D \ d? | 2 [0-4] \ d | 25 [0-5]) \.) {3} (1? \ D \ d? | 2 [0-4] \ d | 25 [0-5])
Morg.
Działa to dobrze w przypadku braku przechwytywania -\b(?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b
Appy,
3
Czy jest 09.09.09.09uważany za ważny adres IP? Jest również dopasowywany przez to wyrażenie regularne. Ale ping wyświetla komunikat o błędzie, taki jak ping: cannot resolve 09.09.09.09: Unknown host. Myślę, że rozsądne byłoby zredukowanie dopasowywania do dopasowania tylko w notacji kropkowo-dziesiętnej. W tym wpisie omówiono główne błędy w adresach IP.
Ruifeng Ma
79
^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$

Zaakceptuj :

127.0.0.1
192.168.1.1
192.168.1.255
255.255.255.255
0.0.0.0
1.1.1.01

Odrzuć :

30.168.1.255.1
127.1
192.168.1.256
-1.2.3.4
1.1.1.1.
3...3

Wypróbuj online za pomocą testów jednostkowych: https://www.debuggex.com/r/-EDZOqxTxhiTncN6/1

Sllouyssgort
źródło
a co z adresem IP „3 ... 3”? 3 ... 3 jest akceptowane przy użyciu tego wyrażenia regularnego
Ankur Loriya
7
A co z wersją 1.1.1.01? Czy jest uważany za prawidłowy adres IPv4? Dzięki.
odieatla
to wyrażenie regularne 1.1.1.01 uważaj za PRAWIDŁOWY adres IPv4. Testy jednostkowe online debuggex.com/r/-EDZOqxTxhiTncN6/1
Sllouyssgort
przy okazji, ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}$uzyskaj ten sam wynik debuggex.com/r/mz_-0dEm3wseIKqK , całkiem podobny z odpowiedzią @Mark Byers
Sllouyssgort
@PriteshAcharya Działa dobrze tutaj.
Kid Diamond
34

Najnowsza, najkrótsza, najmniej czytelna wersja ( 55 znaków )

^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$

Ta wersja wyszukuje skrzynkę 250-5, a następnie sprytnie OR wszystkie możliwe przypadki dla 200-249 100-199 10-99skrzynek. Zauważ, że |)część nie jest pomyłką, ale w rzeczywistości jest ostatnim przypadkiem dla zakresu 0-9. Pominąłem również ?:część grupową bez przechwytywania, ponieważ tak naprawdę nie obchodzą nas przechwycone przedmioty, nie zostałyby one przechwycone, gdybyśmy nie mieli pełnego dopasowania w pierwszej kolejności.

Stara i krótsza wersja (mniej czytelna) ( 63 znaki )

^(?:(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(?!$)|$)){4}$

Starsza (czytelna) wersja ( 70 znaków )

^(?:(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(\.(?!$)|$)){4}$

Używa negatywnego lookahead, (?!)aby usunąć przypadek, w którym adres IP może kończyć się rozszerzeniem.

Najstarsza odpowiedź ( 115 znaków )

^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}
    (?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$

Myślę, że jest to najdokładniejsze i najściślejsze wyrażenie regularne, nie akceptuje rzeczy, na 000.021.01.0.które wygląda większość innych odpowiedzi tutaj i wymaga dodatkowego wyrażenia regularnego, aby odrzucić przypadki podobne do tego - tj. 0Numery początkowe i adres IP kończący się na.

Danail Gabenski
źródło
To jedyna poprawna odpowiedź w tym wątku do tej pory. Inni pomijają takie adresy 0.0.0.0lub akceptują mieszaną notację 033.033.33.033ósemkową / dziesiętną, taką jak 999,999,999,999 lub nawet pozwalają. A co z tym wyrażeniem regularnym, które jest o 10 znaków krótsze niż ta odpowiedź:(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])
anneb
1
@tinmarino Cofnąłem twoją edycję, ponieważ zezwoliła na takie rzeczy jak 192.168.000.1, który nie jest prawidłowym adresem. Każdy, kto chce edytować tę odpowiedź, najpierw skomentuj tutaj, aby uniknąć takich problemów - zwykle odpowiadam dość szybko. Oczywiście zawsze szukam krótszego / lepszego rozwiązania.
Danail Gabenski,
1
@DanailGabenski (i inne) dla pamięci, rozwiązałeś to zastępując ostatnie [01]?[0-9][0-9]?przez, 1[0-9]{2}|[1-9]?[0-9]ponieważ nie lubisz wiodących 0 . Dzięki raz jeszcze ! Twoje rozwiązanie zatrzymam w moim bagażu głównym regex.
Tinmarino,
1
@tinmarino tak, format dziesiętny z kropkami, który stał się standardem dla ipv4, chociaż nie został oficjalnie zaakceptowany, spójrz na poniższe . W szczególności punkt 3, w którym zaproponowano projekt, ale wygasł. Drugim powodem, dla którego tak rygorystycznie sprawdzamy walidację, jest to, że gdy są prezentowane w interfejsie użytkownika, adresy IP z liczbami niedziesiętnymi, takimi jak 023 zamiast 23, sprawiają, że użytkownicy uważają, że jest to błąd / błąd. Prowadzi to również do problemów z weryfikacją / zabezpieczeniami, ponieważ 023 musi zostać przekonwertowane na 23, aby uniknąć duplikatów itp. Dziękujemy za próbę ulepszenia!
Danail Gabenski
1
Można zrobić to krótszy o faktoringu się z [0-9]na 2[0-4], 1i krótszych przypadkach. ^(?:(25[0-5]|(?:2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$
Clayton Singh
12

Adres IPv4 (dokładne przechwycenie) Dopasowania od 0.0.0.0 do 255.255.255.255 Użyj tego wyrażenia regularnego, aby dokładnie dopasować numery IP. Każda z 4 liczb jest przechowywana w grupie przechwytywania, dzięki czemu można uzyskać do nich dostęp w celu dalszego przetwarzania.

\b
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
\b

pobrane z biblioteki JGsoft RegexBuddy

Edycja: ta (\.|$)część wydaje się dziwna

Valerij
źródło
2
Ładny! Zrobiłem wydajniejszą modyfikację tego, co wydaje się działać: "\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$){4}\b- dzięki!
Matthieu Cartier
2
@MatthieuCartier Twój wydajny wzorzec wyrażenia regularnego nie zadziałał dla mnie,
R__raki__
255.255.255.000 nie jest prawidłowym
Stéphane GRILLON
6

Szukałem czegoś podobnego dla adresów IPv4 - wyrażenia regularnego, które również uniemożliwiło weryfikację powszechnie używanych prywatnych adresów IP (192.168.xy, 10.xyz, 172.16.xy), więc użyłem negatywnych wyprzedzeń, aby to osiągnąć:

(?!(10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.).*)
(?!255\.255\.255\.255)(25[0-5]|2[0-4]\d|[1]\d\d|[1-9]\d|[1-9])
(\.(25[0-5]|2[0-4]\d|[1]\d\d|[1-9]\d|\d)){3}

(Oczywiście powinny one znajdować się w jednym wierszu, sformatowane do celów czytelności w 3 oddzielnych wierszach) Wizualizacja wyrażeń regularnych

Debuggex Demo

Może nie być zoptymalizowany pod kątem szybkości, ale działa dobrze, gdy szuka się tylko „prawdziwych” adresów internetowych.

Rzeczy, które zawiodą (i powinny):

0.1.2.3         (0.0.0.0/8 is reserved for some broadcasts)
10.1.2.3        (10.0.0.0/8 is considered private)
172.16.1.2      (172.16.0.0/12 is considered private)
172.31.1.2      (same as previous, but near the end of that range)
192.168.1.2     (192.168.0.0/16 is considered private)
255.255.255.255 (reserved broadcast is not an IP)
.2.3.4
1.2.3.
1.2.3.256
1.2.256.4
1.256.3.4
256.2.3.4
1.2.3.4.5
1..3.4

Adresy IP, które będą (i powinny) działać:

1.0.1.0         (China)
8.8.8.8         (Google DNS in USA)
100.1.2.3       (USA)
172.15.1.2      (USA)
172.32.1.2      (USA)
192.167.1.2     (Italy)

Podawana na wypadek, gdyby ktoś inny szukał weryfikacji „internetowych adresów IP bez wspólnych adresów prywatnych”

PhillipHolmes
źródło
5

Myślę, że wiele osób czytających ten post będzie szukało prostszych wyrażeń regularnych, nawet jeśli pasują do niektórych technicznie nieprawidłowych adresów IP. (I, jak zauważono w innym miejscu, regex i tak prawdopodobnie nie jest odpowiednim narzędziem do prawidłowego sprawdzania poprawności adresu IP).

Usuń ^i, w razie potrzeby, wymienić $z\b , jeśli nie chcesz, aby dopasować początek / koniec linii.

Podstawowe wyrażenie regularne (BRE) (testowane na GNU grep, GNU sed i vim):

/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/

Rozszerzone wyrażenie regularne (ERE):

/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/

lub:

/^([0-9]+(\.|$)){4}/

Wyrażenie regularne kompatybilne z Perl (PCRE) (testowane na Perl 5.18):

/^\d+\.\d+\.\d+\.\d+$/

lub:

/^(\d+(\.|$)){4}/

Ruby (testowany na Ruby 2.1):

Chociaż Ruby miał być PCRE, z jakiegokolwiek powodu zezwalał na to wyrażenie regularne niedozwolone przez Perl 5.18:

/^(\d+[\.$]){4}/

Moje testy na to wszystko są tutaj .

Alex Harvey
źródło
3

To trochę dłużej niż niektóre, ale właśnie tego używam do dopasowywania adresów IPv4. Proste bez kompromisów.

^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$
Mickstar
źródło
3

Powyższe odpowiedzi są prawidłowe, ale co, jeśli adres IP nie znajduje się na końcu wiersza i znajduje się między tekstem. To wyrażenie regularne będzie nawet działać.

kod: '\b((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.)){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\b'

wejściowy plik tekstowy:

ip address 0.0.0.0 asfasf
 sad sa 255.255.255.255 cvjnzx
zxckjzbxk  999.999.999.999 jshbczxcbx
sjaasbfj 192.168.0.1 asdkjaksb
oyo 123241.24121.1234.3423 yo
yo 0000.0000.0000.0000 y
aw1a.21asd2.21ad.21d2
yo 254.254.254.254 y0
172.24.1.210 asfjas
200.200.200.200
000.000.000.000
007.08.09.210
010.10.30.110

tekst wyjściowy:

0.0.0.0
255.255.255.255
192.168.0.1
254.254.254.254
172.24.1.210
200.200.200.200
Kushagra Gupta
źródło
1
Zostało to ocenione negatywnie, dopóki nie oddałem głosu. Próbuję to zrobić od (więcej godzin, niż chcę się przyznać). Nie przechwyci linii, która ma więcej niż jedną kropkę w linii, ale w moim przypadku mogę z tym żyć. To doskonała odpowiedź, potrzeba więcej głosów!
anastrofa
3

'' 'Ten kod działa dla mnie i jest taki prosty.

Tutaj wziąłem wartość ip i próbuję dopasować ją za pomocą wyrażenia regularnego.

ip="25.255.45.67"    

op=re.match('(\d+).(\d+).(\d+).(\d+)',ip)

if ((int(op.group(1))<=255) and (int(op.group(2))<=255) and int(op.group(3))<=255) and (int(op.group(4))<=255)):

print("valid ip")

else:

print("Not valid")

Powyższy warunek sprawdza, czy wartość przekracza 255 dla wszystkich 4 oktetów, a następnie jest nieprawidłowy. Ale przed zastosowaniem warunku musimy przekonwertować je na liczby całkowite, ponieważ wartość jest w ciągu.

group (0) drukuje dopasowane wyjście, podczas gdy group (1) drukuje pierwszą dopasowaną wartość, a tutaj jest to „25” i tak dalej. '' '

Shruti Lakkihal
źródło
Witamy w StackOverflow. Byłoby wspaniale, gdybyś mógł poświęcić kilka słów na wyjaśnienie, dlaczego Twoja odpowiedź powinna rozwiązać problem OP. Odpowiedzi zawierające tylko kod są ogólnie złymi odpowiedziami, ponieważ nie pomagają innym programistom zrozumieć, co zrobili źle.
Davide Vitali,
Użyj odpowiednich wcięć w kodzie, aby był czytelny dla użytkowników
Syed Mehtab Hassan
2

Udało mi się skonstruować wyrażenie regularne ze wszystkich innych odpowiedzi.

(25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9][0-9]|[0-9]?)(\.(25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9][0-9]|[0-9]?)){3}
Vicky
źródło
Zgodnie ze standardem Ethernet IEEE 802.x walidacja IP to zakres adresów 0.xxx >>> nie powinna być dozwolona - nieprawidłowy adres IP. # 1.Zakres IP zaczyna się od 1.xxx do 126.xxx >>>> może być skonfigurowany. # 2. zakres adresów IP 127.xxx >>>> nie powinien być dozwolony - nieprawidłowy adres IP. # 3. Zakres adresów IP od 128.xxx do 223.xxx >> można ustawić. lepszy sposób obsługi jest sugerowany poniżej: ^ (22 [0-3] | 2 [0-1] [0-9] | [1] [0-9] [0-9]? | [1-9] ] [0-9] | [1-9]) \. (25 [0-5] | 2 [0-4] [0-9] | [01]? [0-9] [0-9]? ) \. (25 [0–5] | 2 [0–4] [0–9] | [01]? [0–9] [0–9]?) \. (25 [0–4] | 2 [0-4] [0-9] | [01]? [0-9] [0-9]?) $
Yogesh Aggarwal
2
/^(?:(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(?1)$/m
Etienne Gautier
źródło
2

Dla liczby od 0 do 255 używam tego wyrażenia regularnego:

(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))

Powyższe wyrażenie regularne będzie pasowało do liczby całkowitej od 0 do 255, ale nie będzie pasowało do 256.

Więc dla IPv4 używam tego wyrażenia regularnego:

^(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})$

Jest w tej strukturze: ^(N)((\.(N)){3})$gdzie N jest wyrażeniem regularnym używanym do dopasowania liczby od 0 do 255.
To wyrażenie regularne będzie pasowało do adresu IP, jak poniżej:

0.0.0.0
192.168.1.2

ale nie te poniżej:

10.1.0.256
1.2.3.
127.0.1-2.3

W przypadku CIDR IPv4 (bezklasowy routing między domenami) używam tego wyrażenia regularnego:

^(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})\/(([0-9])|([12][0-9])|(3[0-2]))$

Jest w tej strukturze: ^(N)((\.(N)){3})\/M$gdzie N jest wyrażeniem regularnym używanym do dopasowania liczby od 0 do 255, a M jest wyrażeniem regularnym używanym do dopasowania liczby od 0 do 32.
To wyrażenie regularne będzie pasowało do CIDR, jak poniżej:

0.0.0.0/0
192.168.1.2/32

ale nie te poniżej:

10.1.0.256/16
1.2.3./24
127.0.0.1/33

A dla listy CIDR IPv4, jak "10.0.0.0/16", "192.168.1.1/32"ja używam tego wyrażenia regularnego:

^("(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})\/(([0-9])|([12][0-9])|(3[0-2]))")((,([ ]*)("(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})\/(([0-9])|([12][0-9])|(3[0-2]))"))*)$

Jest w tej strukturze: ^(“C”)((,([ ]*)(“C”))*)$gdzie C jest wyrażeniem regularnym używanym do dopasowania CIDR (np. 0.0.0.0/0).
To wyrażenie regularne będzie pasowało do listy CIDR, jak poniżej:

“10.0.0.0/16”,”192.168.1.2/32”, “1.2.3.4/32”

ale nie te poniżej:

“10.0.0.0/16” 192.168.1.2/32 “1.2.3.4/32”

Może może się to skrócić, ale dla mnie jest to łatwe do zrozumienia przeze mnie tak dobrze.

Mam nadzieję, że to pomoże!

congacon
źródło
Witamy w SO, doceniamy Twój wkład! Czy mógłbyś wyjaśnić trochę, co robią różne wyrażenia regularne (w szczególności ostatnie)?
B - rian
1

Z maską podsieci:

^$|([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\
.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\
.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\
.([01]?\\d\\d?|2[0-4]\\d|25[0-5])
((/([01]?\\d\\d?|2[0-4]\\d|25[0-5]))?)$
hsuk
źródło
1
(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))\.){3}(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2})))

Testuj, aby znaleźć dopasowania w tekście, https://regex101.com/r/9CcMEN/2

Poniżej przedstawiono zasady definiujące prawidłowe kombinacje w każdym numerze adresu IP:

  • Dowolna jedno- lub dwucyfrowa liczba.
  • Dowolna trzycyfrowa liczba zaczynająca się od 1.

  • Dowolna liczba trzycyfrowa rozpoczynająca się 2jeśli druga cyfra jest 0 przez 4.

  • Dowolna liczba trzycyfrowa początek ze 25jeżeli trzecia cyfra jest 0 przez 5.

Zacznijmy od (((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))\.)zestawu czterech zagnieżdżonych podwyrażeń, a przyjrzymy się im w odwrotnej kolejności. (\d{1,2})dopasowuje dowolną jedno- lub dwucyfrową liczbę lub liczby 0do 99. (1\d{2})dopasowuje dowolną trzycyfrową liczbę zaczynającą się od 1( 1po której następują dowolne dwie cyfry) lub cyfr 100do 199. (2[0-4]\d)dopasowuje liczby 200do 249. (25[0-5])dopasowuje liczby 250do 255. Każde z tych podwyrażeń jest zawarte w innym wyrażeniu podrzędnym z |między każdym z nich (tak, że jedno z czterech podwyrażeń musi być zgodne, a nie wszystkie). Po \.dopasowaniu zakresu liczb ) jest umieszczany w kolejnym podwyrażeniu i powtarzany trzykrotnie za pomocą. , a następnie całej serii (wszystkie opcje liczbowe plus\.{3}. Na koniec zakres liczb jest powtarzany (tym razem bez końca \.), aby dopasować końcowy numer adresu IP. Ograniczając każdą z czterech liczb do wartości między 0a 255, ten wzorzec może rzeczywiście dopasować prawidłowe adresy IP i odrzucić nieprawidłowe adresy.

Fragment z: Ben Forta. „Nauka wyrażeń regularnych”.


Jeśli żaden znak nie jest wymagany na początku adresu IP ani na końcu ^i $należy użyć odpowiednio metaznaków.

^(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))\.){3}(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2})))$

Przetestuj, aby znaleźć dopasowania w tekście, https://regex101.com/r/uAP31A/1

snr
źródło
1

Starałem się, żeby było to trochę prostsze i krótsze.

^(([01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}([01]?\d{1,2}|2[0-4]\d|25[0-5])$

Jeśli szukasz java / kotlin:

^(([01]?\\d{1,2}|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d{1,2}|2[0-4]\\d|25[0-5])$

Jeśli ktoś chce wiedzieć, jak to działa, to wyjaśnienie. To naprawdę takie proste. Po prostu spróbuj: p:

 1. ^.....$: '^' is the starting and '$' is the ending.

 2. (): These are called a group. You can think of like "if" condition groups.

 3. |: 'Or' condition - as same as most of the programming languages.

 4. [01]?\d{1,2}: '[01]' indicates one of the number between 0 and 1. '?' means '[01]' is optional. '\d' is for any digit between 0-9 and '{1,2}' indicates the length can be between 1 and 2. So here the number can be 0-199.

 5. 2[0-4]\d: '2' is just plain 2. '[0-4]' means a number between 0 to 4. '\d' is for any digit between 0-9. So here the number can be 200-249.

 6. 25[0-5]: '25' is just plain 25. '[0-5]' means a number between 0 to 5. So here the number can be 250-255.

 7. \.: It's just plan '.'(dot) for separating the numbers.

 8. {3}: It means the exact 3 repetition of the previous group inside '()'.

 9. ([01]?\d{1,2}|2[0-4]\d|25[0-5]): Totally same as point 2-6

Matematycznie wygląda to tak:

(0-199 OR 200-249 OR 250-255).{Repeat exactly 3 times}(0-199 OR 200-249 OR 250-255)

Tak więc, jak zwykle widać, jest to wzorzec adresów IP. Mam nadzieję, że pomoże to trochę zrozumieć wyrażenia regularne. : p

Arhan Ashik
źródło
1

Starałem się, żeby było to trochę prostsze i krótsze.

^ (([01]? \ D {1,2} | 2 [0-4] \ d | 25 [0-5]).) {3} ([01]? \ D {1,2} | 2 [0-4] \ d | 25 [0-5]) $

Jeśli szukasz java / kotlin:

^ (([01]? \ D {1,2} | 2 [0-4] \ d | 25 [0-5]) \.) {3} ([01]? \ D {1,2} | 2 [0-4] \ d | 25 [0-5]) $

Jeśli ktoś chce wiedzieć, jak to działa, to wyjaśnienie. To naprawdę takie proste. Po prostu spróbuj: p:

 1. ^.....$: '^' is the starting and '$' is the ending.

 2. (): These are called a group. You can think of like "if" condition groups.

 3. |: 'Or' condition - as same as most of the programming languages.

 4. [01]?\d{1,2}: '[01]' indicates one of the number between 0 and 1. '?' means '[01]' is optional. '\d' is for any digit between 0-9 and '{1,2}' indicates the length can be between 1 and 2. So here the number can be 0-199.

 5. 2[0-4]\d: '2' is just plain 2. '[0-4]' means a number between 0 to 4. '\d' is for any digit between 0-9. So here the number can be 200-249.

 6. 25[0-5]: '25' is just plain 25. '[0-5]' means a number between 0 to 5. So here the number can be 250-255.

 7. \.: It's just plan '.'(dot) for separating the numbers.

 8. {3}: It means the exact 3 repetition of the previous group inside '()'.

 9. ([01]?\d{1,2}|2[0-4]\d|25[0-5]): Totally same as point 2-6

Matematycznie wygląda to tak:

(0-199 OR 200-249 OR 250-255).{Repeat exactly 3 times}(0-199 OR 200-249 OR 250-255)

Tak więc, jak zwykle widać, jest to wzorzec adresów IP. Mam nadzieję, że pomoże to trochę zrozumieć wyrażenia regularne. : p

Arhan Ashik
źródło
0
    const char*ipv4_regexp = "\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
    "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
    "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
    "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b";

Dostosowałem wyrażenie regularne pobrane z biblioteki JGsoft RegexBuddy do języka C (regcomp / regexec) i odkryłem, że działa, ale w niektórych systemach operacyjnych, takich jak Linux, jest mały problem. To wyrażenie regularne akceptuje adres ipv4, taki jak 192.168.100.009, gdzie 009 w Linuksie jest uważane za wartość ósemkową, więc adres nie jest tym, o którym myślałeś. Zmieniłem to wyrażenie regularne w następujący sposób:

    const char* ipv4_regex = "\\b(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
           "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
           "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
           "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\b";

używanie tego wyrażenia regularnego teraz 192.168.100.009 nie jest prawidłowym adresem IPv4, podczas gdy 192.168.100.9 jest w porządku.

Zmodyfikowałem również wyrażenie regularne dla adresu multiemisji i wygląda to następująco:

    const char* mcast_ipv4_regex = "\\b(22[4-9]|23[0-9])\\."
                        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
                        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]?)\\."
                        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\b";

Myślę, że musisz dostosować wyrażenie regularne do języka, którego używasz do tworzenia aplikacji

Umieściłem przykład w javie:

    package utility;

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    public class NetworkUtility {

        private static String ipv4RegExp = "\\b(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d?)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d?)\\b";

        private static String ipv4MulticastRegExp = "2(?:2[4-9]|3\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d?|0)){3}";

        public NetworkUtility() {

        }

        public static boolean isIpv4Address(String address) {
            Pattern pattern = Pattern.compile(ipv4RegExp);
            Matcher matcher = pattern.matcher(address);

            return matcher.matches();
        }

        public static boolean isIpv4MulticastAddress(String address) {
             Pattern pattern = Pattern.compile(ipv4MulticastRegExp);
             Matcher matcher = pattern.matcher(address);

             return matcher.matches();
        }
    }
Fabio Stafforte
źródło
0
-bash-3.2$ echo "191.191.191.39" | egrep 
  '(^|[^0-9])((2([6-9]|5[0-5]?|[0-4][0-9]?)?|1([0-9][0-9]?)?|[3-9][0-9]?|0)\.{3}
     (2([6-9]|5[0-5]?|[0-4][0-9]?)?|1([0-9][0-9]?)?|[3-9][0-9]?|0)($|[^0-9])'

>> 191.191.191.39

(To jest DFA, który dopasowuje całą przestrzeń addr (w tym transmisje itp.) I nic więcej.

Jonathzen
źródło
0

Myślę, że ten jest najkrótszy.

^(([01]?\d\d?|2[0-4]\d|25[0-5]).){3}([01]?\d\d?|2[0-4]\d|25[0-5])$
Altan Gokcek
źródło
0

Uważam, że ten przykład jest bardzo przydatny, a ponadto pozwala na różne notacje ipv4.

przykładowy kod w pythonie:

    def is_valid_ipv4(ip4):
    """Validates IPv4 addresses.
    """
    import re
    pattern = re.compile(r"""
        ^
        (?:
          # Dotted variants:
          (?:
            # Decimal 1-255 (no leading 0's)
            [3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
          |
            0x0*[0-9a-f]{1,2}  # Hexadecimal 0x0 - 0xFF (possible leading 0's)
          |
            0+[1-3]?[0-7]{0,2} # Octal 0 - 0377 (possible leading 0's)
          )
          (?:                  # Repeat 0-3 times, separated by a dot
            \.
            (?:
              [3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
            |
              0x0*[0-9a-f]{1,2}
            |
              0+[1-3]?[0-7]{0,2}
            )
          ){0,3}
        |
          0x0*[0-9a-f]{1,8}    # Hexadecimal notation, 0x0 - 0xffffffff
        |
          0+[0-3]?[0-7]{0,10}  # Octal notation, 0 - 037777777777
        |
          # Decimal notation, 1-4294967295:
          429496729[0-5]|42949672[0-8]\d|4294967[01]\d\d|429496[0-6]\d{3}|
          42949[0-5]\d{4}|4294[0-8]\d{5}|429[0-3]\d{6}|42[0-8]\d{7}|
          4[01]\d{8}|[1-3]\d{0,9}|[4-9]\d{0,8}
        )
        $
    """, re.VERBOSE | re.IGNORECASE)
    return pattern.match(ip4) <> None
internety
źródło
0
((\.|^)(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0$)){4}

To wyrażenie regularne nie zaakceptuje 08.8.8.8 lub 8.08.8.8 lub 8.8.08.8 lub 8.8.8.08

sudistack
źródło
ten pomija, na przykład 127.0.0.1 i 0.0.0.0
połącz
^ ((\. | ^) (25 [0–5] | 2 [0–4] [0–9] | 1 [0–9] [0–9] | [1–9] [0–9] ? | [0–9]? | 0)) ((\. | ^) (25 [0–5] | 2 [0–4] [0–9] | 1 [0–9] [0–9] | [1-9] [0-9]? | 0)) {2}. ((25 [0-5] | 2 [0-4] [0-9] | 1 [0-9] [0- 9] | [1-9] [0-9]? | 0) $)
sudistack
1
Prawidłowe jest odrzucanie wiodących zer, zgodnie ze specyfikacją.
John Haugeland
0

Znajduje prawidłowe adresy IP, o ile adres IP jest zawinięty wokół dowolnego znaku innego niż cyfry (za lub przed adresem IP). 4 Utworzono odwołania wsteczne: $ + {pierwsza}. $ + {Druga}. $ + {Trzecia}. $ + {Dalej}

Find String:
#any valid IP address
(?<IP>(?<![\d])(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))
#only valid private IP address RFC1918
(?<IP>(?<![\d])(:?(:?(?<first>10)[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5])))|(:?(?<first>172)[\.](?<second>(:?1[6-9])|(:?2[0-9])|(:?3[0-1])))|(:?(?<first>192)[\.](?<second>168)))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))

Notepad++ Replace String Option 1: Replaces the whole IP (NO Change):
$+{IP}

Notepad++ Replace String Option 2: Replaces the whole IP octect by octect (NO Change)
$+{first}.$+{second}.$+{third}.$+{forth}

Notepad++ Replace String Option 3: Replaces the whole IP octect by octect (replace 3rd octect value with 0)
$+{first}.$+{second}.0.$+{forth}
NOTE: The above will match any valid IP including 255.255.255.255 for example and change it to 255.255.0.255 which is wrong and not very useful of course.

Zastępowanie części każdego oktektu rzeczywistą wartością, ale możesz zbudować własne wyszukiwanie i zamianę, co jest rzeczywiście przydatne do poprawiania adresów IP w plikach tekstowych:

for example replace the first octect group of the original Find regex above:
(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))
with
(?<first>10)

and
(?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))
with
(?<second>216)
and you are now matching addresses starting with first octect 192 only

Find on notepad++:
(?<IP>(?<![\d])(?<first>10)[\.](?<second>216)[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))

Nadal możesz wykonać Zastąp, używając grup odniesień wstecznych w dokładnie taki sam sposób jak poprzednio.

Możesz zobaczyć, w jaki sposób powyższe pasowało poniżej:

cat ipv4_validation_test.txt
Full Match:
0.0.0.1
12.108.1.34
192.168.1.1
10.249.24.212
10.216.1.212
192.168.1.255
255.255.255.255
0.0.0.0


Partial Match (IP Extraction from line)
30.168.1.0.1
-1.2.3.4
sfds10.216.24.23kgfd
da11.15.112.255adfdsfds
sfds10.216.24.23kgfd


NO Match
1.1.1.01
3...3
127.1.
192.168.1..
192.168.1.256
da11.15.112.2554adfdsfds
da311.15.112.255adfdsfds

Korzystając z grep, możesz zobaczyć wyniki poniżej:

From grep:
grep -oP '(?<IP>(?<![\d])(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))' ipv4_validation_test.txt
0.0.0.1
12.108.1.34
192.168.1.1
10.249.24.212
10.216.1.212
192.168.1.255
255.255.255.255
0.0.0.0
30.168.1.0
1.2.3.4
10.216.24.23
11.15.112.255
10.216.24.23


grep -P '(?<IP>(?<![\d])(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))' ipv4_validation_test.txt
0.0.0.1
12.108.1.34
192.168.1.1
10.249.24.212
10.216.1.212
192.168.1.255
255.255.255.255
0.0.0.0
30.168.1.0.1
-1.2.3.4
sfds10.216.24.23kgfd
da11.15.112.255adfdsfds
sfds10.216.24.23kgfd


#matching ip addresses starting with 10.216
grep -oP '(?<IP>(?<![\d])(?<first>10)[\.](?<second>216)[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))' ipv4_validation_test.txt
10.216.1.212
10.216.24.23
10.216.24.23
rda
źródło
0

Adres IPv4 to bardzo skomplikowana sprawa.

Uwaga : Wcięcia i podszewka służą jedynie do celów ilustracyjnych i nie występują w prawdziwym wyrażeniu regularnym.

\b(
  ((
    (2(5[0-5]|[0-4][0-9])|1[0-9]{2}|[1-9]?[0-9])
  |
    0[Xx]0*[0-9A-Fa-f]{1,2}
  |
    0+[1-3]?[0-9]{1,2}
  )\.){1,3}
  (
    (2(5[0-5]|[0-4][0-9])|1[0-9]{2}|[1-9]?[0-9])
  |
    0[Xx]0*[0-9A-Fa-f]{1,2}
  |
    0+[1-3]?[0-9]{1,2}
  )
|
  (
    [1-3][0-9]{1,9}
  |
    [1-9][0-9]{,8}
  |
    (4([0-1][0-9]{8}
      |2([0-8][0-9]{7}
        |9([0-3][0-9]{6}
          |4([0-8][0-9]{5}
            |9([0-5][0-9]{4}
              |6([0-6][0-9]{3}
                |7([0-1][0-9]{2}
                  |2([0-8][0-9]{1}
                    |9([0-5]
    ))))))))))
  )
|
  0[Xx]0*[0-9A-Fa-f]{1,8}
|
  0+[1-3]?[0-7]{,10}
)\b

Te adresy IPv4 są sprawdzane przez powyższe wyrażenie regularne.

127.0.0.1
2130706433
0x7F000001
017700000001
0x7F.0.0.01 # Mixed hex/dec/oct
000000000017700000001 # Have as many leading zeros as you want
0x0000000000007F000001 # Same as above
127.1
127.0.1

Te są odrzucane.

256.0.0.1
192.168.1.099 # 099 is not a valid number
4294967296 # UINT32_MAX + 1
0x100000000
020000000000
iBug
źródło
0

^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.)){3}+((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))$


Powyżej będzie wyrażenie regularne dla adresu IP, takiego jak: 221.234.000.112 również dla 221.234.0.112, 221.24.03.112, 221.234.0.1


Możesz sobie wyobrazić każdy rodzaj adresu jak powyżej

Ram Sharma
źródło
0

Użyłbym PCRE i definesłowa kluczowego:

/^
 ((?&byte))\.((?&byte))\.((?&byte))\.((?&byte))$
 (?(DEFINE)
     (?<byte>25[0-5]|2[0-4]\d|[01]?\d\d?))
/gmx

Próbny: https://regex101.com/r/IB7j48/2

Ma to na celu uniknięcie (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)czterokrotnego powtórzenia wzoru. Inne rozwiązania, takie jak to poniżej, działają dobrze, ale nie obejmują każdej grupy, jak by tego wymagało wiele osób.

/^((\d+?)(\.|$)){4}/ 

Jedynym innym sposobem na utworzenie 4 grup przechwytywania jest czterokrotne powtórzenie wzoru:

/^(?<one>\d+)\.(?<two>\d+)\.(?<three>\d+)\.(?<four>\d+)$/

Przechwytywanie ipv4 w perlu jest więc bardzo łatwe

$ echo "Hey this is my IP address 138.131.254.8, bye!" | \
  perl -ne 'print "[$1, $2, $3, $4]" if \
    /\b((?&byte))\.((?&byte))\.((?&byte))\.((?&byte))
     (?(DEFINE)
        \b(?<byte>25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))
    /x'

[138, 131, 254, 8]
nowox
źródło
0

Najbardziej precyzyjnym, prostym i kompaktowym wyrażeniem regularnym IPv4, jaki mogę sobie wyobrazić, jest

^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$

Ale co z wydajnością / wydajnością ... Przepraszam, nie wiem, kogo to obchodzi?

fuweichin
źródło
0

Spróbuj tego:

\b(([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\.(2[0-5][0-5]|1[0-9][0-9]|[1-9][0-9]|[1-9]))\b
AAP
źródło
0
ip address can be from 0.0.0.0 to 255.255.255.255

(((0|1)?[0-9][0-9]?|2[0-4][0-9]|25[0-5])[.]){3}((0|1)?[0-9][0-9]?|2[0-4][0-9]|25[0-5])$

(0|1)?[0-9][0-9]? - checking value from 0 to 199
2[0-4][0-9]- checking value from 200 to 249
25[0-5]- checking value from 250 to 255
[.] --> represent verify . character 
{3} --> will match exactly 3
$ --> end of string
Deepak_Mahalingam
źródło
0

Poniżej znajduje się wyrażenie regularne służące do weryfikacji adresu IP.

^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
Dilip Paudel
źródło
0

Łatwy sposób

((25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9][0-9]{0,1})\.){3}(25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9][0-9]{0,1})

Próbny

BabiBN
źródło