it-swarm.asia

Ekspresi reguler untuk mencocokkan nama host DNS atau Alamat IP?

Adakah yang memiliki ekspresi reguler yang berguna yang cocok dengan nama host DNS atau alamat IP yang sah?

Sangat mudah untuk menulis yang bekerja 95% dari waktu, tetapi saya berharap untuk mendapatkan sesuatu yang diuji dengan baik agar sama persis dengan spesifikasi RFC terbaru untuk nama host DNS.

352
DonGar

Anda dapat menggunakan ekspresi reguler berikut secara terpisah atau dengan menggabungkannya dalam ekspresi OR gabungan.

ValidIpAddressRegex = "^(([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])$";

ValidHostnameRegex = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$";

ValidIpAddressRegex cocok dengan alamat IP yang valid dan ValidHostnameRegex nama Host yang valid. Bergantung pada bahasa yang Anda gunakan\bisa harus lolos dengan \.


ValidHostnameRegex berlaku sesuai RFC 112 . Awalnya, RFC 952 menentukan bahwa segmen nama host tidak dapat dimulai dengan angka.

http://en.wikipedia.org/wiki/Hostname

Spesifikasi asli dari nama host di RFC 952 , mengamanatkan bahwa label tidak dapat dimulai dengan angka atau dengan tanda hubung, dan tidak boleh diakhiri dengan tanda hubung. Namun, spesifikasi berikutnya ( RFC 112 ) mengizinkan label nama host untuk memulai dengan angka.

Valid952HostnameRegex = "^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$";
510
Jorge Ferreira

Regex hostname dari smink tidak memperhatikan batasan pada panjang masing-masing label dalam nama host. Setiap label dalam nama host yang valid mungkin tidak lebih dari 63 oktet.

ValidHostnameRegex = "^ ([a-zA-Z0-9] | [a-zA-Z0-9] [a-zA-Z0-9\-] {0,61} [a-zA-Z0-9])\
 (\. ([a-zA-Z0-9] | [a-zA-Z0-9] [a-zA-Z0-9\-] {0,61} [a-zA- Z0-9])) * $ "

Perhatikan bahwa garis miring terbalik pada akhir baris pertama (di atas) adalah sintaks Unix Shell untuk memisahkan garis panjang. Itu bukan bagian dari ekspresi reguler itu sendiri.

Ini hanya ekspresi reguler saja dalam satu baris:

^ ([a-zA-Z0-9] | [a-zA-Z0-9] [a-zA-Z0-9\-] {0,61} [a-zA-Z0-9]) (\. ([a-zA-Z0-9] | [a-zA-Z0-9] [a-zA-Z0-9\-] {0,61} [a-zA-Z0-9])) * $

Anda juga harus memeriksa secara terpisah bahwa total panjang nama host tidak boleh melebihi 255 karakter. Untuk informasi lebih lanjut, silakan berkonsultasi dengan RFC-952 dan RFC-1123.

60

Untuk mencocokkan alamat IP yang valid gunakan regex berikut:

(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]?)){3}

dari pada:

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

Penjelasan

Banyak mesin regex cocok dengan kemungkinan pertama dalam urutan OR. Misalnya, coba regex berikut:

10.48.0.200

Uji

Uji perbedaan antara baik vs buruk

30
Alban

Saya sepertinya tidak dapat mengedit posting teratas, jadi saya akan menambahkan jawaban saya di sini.

Untuk hostname - jawaban mudah, pada contoh egrep di sini - http: //www.linuxinsight.com/how_to_grep_for_ip_addresses_using_the_gnu_egrep_utility.html

egrep '([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}'

Meskipun case tidak memperhitungkan nilai-nilai seperti 0 dalam octet pertama, dan nilai lebih dari 254 (addres ip) atau 255 (netmask). Mungkin pernyataan tambahan jika akan membantu.

Adapun nama host legal dns, asalkan Anda hanya memeriksa nama host internet (dan bukan intranet), saya menulis snipped berikut, campuran dari Shell/php tetapi harus berlaku sebagai ungkapan reguler apa pun.

pertama-tama pergi ke situs web ietf, unduh dan parsing daftar nama domain level 1 legal:

tld=$(curl -s http://data.iana.org/TLD/tlds-alpha-by-domain.txt |  sed 1d  | cut -f1 -d'-' | tr '\n' '|' | sed 's/\(.*\)./\1/')
echo "($tld)"

Itu akan memberi Anda sepotong kode ulang Nice yang memeriksa legalitas nama domain top, seperti .com .org atau .ca

Kemudian tambahkan bagian pertama dari ekspresi sesuai dengan pedoman yang ditemukan di sini - http: //www.domainit.com/support/faq.mhtml?category=Domain_FAQ&question=9 (kombinasi alfanumerik dan simbol '-' apa pun, tanda hubung tidak boleh dalam awal atau akhir oktet.

(([a-z0-9]+|([a-z0-9]+[-]+[a-z0-9]+))[.])+

Kemudian kumpulkan semuanya (contoh PHP preg_match):

$pattern = '/^(([a-z0-9]+|([a-z0-9]+[-]+[a-z0-9]+))[.])+(AC|AD|AE|AERO|AF|AG|AI|AL|AM|AN|AO|AQ|AR|ARPA|AS|ASIA|AT|AU|AW|AX|AZ|BA|BB|BD|BE|BF|BG|BH|BI|BIZ|BJ|BM|BN|BO|BR|BS|BT|BV|BW|BY|BZ|CA|CAT|CC|CD|CF|CG|CH|CI|CK|CL|CM|CN|CO|COM|COOP|CR|CU|CV|CX|CY|CZ|DE|DJ|DK|DM|DO|DZ|EC|EDU|EE|EG|ER|ES|ET|EU|FI|FJ|FK|FM|FO|FR|GA|GB|Gd|GE|GF|GG|GH|GI|GL|GM|GN|GOV|GP|GQ|GR|GS|GT|GU|GW|GY|HK|HM|HN|HR|HT|HU|ID|IE|IL|IM|IN|INFO|INT|IO|IQ|IR|IS|IT|JE|JM|JO|JOBS|JP|KE|KG|KH|KI|KM|KN|KP|KR|KW|KY|KZ|LA|LB|LC|LI|LK|LR|LS|LT|LU|LV|LY|MA|MC|MD|ME|MG|MH|MIL|MK|ML|MM|MN|MO|MOBI|MP|MQ|MR|MS|MT|MU|MUSEUM|MV|MW|MX|MY|MZ|NA|NAME|NC|NE|NET|NF|NG|NI|NL|NO|NP|NR|NU|NZ|OM|ORG|PA|PE|PF|PG|PH|PK|PL|PM|PN|PR|PRO|PS|PT|PW|PY|QA|RE|RO|RS|RU|RW|SA|SB|SC|SD|SE|SG|SH|SI|SJ|SK|SL|SM|SN|SO|SR|ST|SU|SV|SY|SZ|TC|TD|TEL|TF|TG|TH|TJ|TK|TL|TM|TN|TO|TP|TR|TRAVEL|TT|TV|TW|TZ|UA|UG|UK|US|UY|UZ|VA|VC|VE|VG|VI|VN|VU|WF|WS|XN|XN|XN|XN|XN|XN|XN|XN|XN|XN|XN|YE|YT|YU|ZA|ZM|ZW)[.]?$/i';

    if (preg_match, $pattern, $matching_string){
    ... do stuff
    }

Anda mungkin juga ingin menambahkan pernyataan if untuk memeriksa string yang Anda periksa lebih pendek dari 256 karakter - http://www.ops.ietf.org/lists/namedroppers/namedroppers.2003/msg00964.html

4
Alex Volkov
def isValidHostname(hostname):

    if len(hostname) > 255:
        return False
    if hostname[-1:] == ".":
        hostname = hostname[:-1]   # strip exactly one dot from the right,
                                   #  if present
    allowed = re.compile("(?!-)[A-Z\d-]{1,63}(?<!-)$", re.IGNORECASE)
    return all(allowed.match(x) for x in hostname.split("."))
2
PythonDev

Perlu dicatat bahwa ada perpustakaan untuk sebagian besar bahasa yang melakukan ini untuk Anda, sering dibangun ke dalam perpustakaan standar. Dan pustaka-pustaka itu cenderung diperbarui lebih sering daripada kode yang Anda salin dari jawaban Stack Overflow empat tahun lalu dan lupa. Dan tentu saja mereka juga akan secara umum mengurai alamat menjadi beberapa bentuk yang dapat digunakan, daripada hanya memberi Anda kecocokan dengan sekelompok kelompok.

Misalnya, mendeteksi dan mem-parsing IPv4 di (POSIX) C:

#include <arpa/inet.h>
#include <stdio.h>

int main(int argc, char *argv[]) {
  for (int i=1; i!=argc; ++i) {
    struct in_addr addr = {0};
    printf("%s: ", argv[i]);
    if (inet_pton(AF_INET, argv[i], &addr) != 1)
      printf("invalid\n");
    else
      printf("%u\n", addr.s_addr);
  }
  return 0;
}

Jelas, fungsi-fungsi seperti itu tidak akan berfungsi jika Anda mencoba, misalnya, menemukan semua alamat yang valid dalam pesan obrolan — tetapi bahkan di sana, mungkin lebih mudah untuk menggunakan regex sederhana namun terlalu bersemangat untuk menemukan kecocokan potensial, dan kemudian menggunakan perpustakaan untuk menguraikannya.

Misalnya, dalam Python:

>>> import ipaddress
>>> import re
>>> msg = "My address is 192.168.0.42; 192.168.0.420 is not an address"
>>> for maybeip in re.findall(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', msg):
...     try:
...         print(ipaddress.ip_address(maybeip))
...     except ValueError:
...         pass
2
abarnert

Saya pikir ini adalah regex validasi Ip terbaik. tolong periksa sekali !!!

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

Ini berfungsi untuk alamat IP yang valid:

regex = '^([0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-5][0-5])[.]([0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-5][0-5])[.]([0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-5][0-5])[.]([0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-5][0-5])$'
1
aliasav
/^(?:[a-zA-Z0-9]+|[a-zA-Z0-9][-a-zA-Z0-9]+[a-zA-Z0-9])(?:\.[a-zA-Z0-9]+|[a-zA-Z0-9][-a-zA-Z0-9]+[a-zA-Z0-9])?$/

localhost же есть

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

Kerangka kerja Jaringan baru telah menyediakan inisialisasi untuk struct IPv4Address dan struct IPv6Address yang menangani bagian alamat IP dengan sangat mudah. Melakukan ini di IPv6 dengan regex sangat sulit dengan semua aturan pemendekan.

Sayangnya saya tidak punya jawaban elegan untuk nama host.

Perhatikan bahwa Kerangka kerja jaringan baru-baru ini, sehingga mungkin memaksa Anda untuk mengkompilasi untuk versi OS terbaru.

import Network
let tests = ["192.168.4.4","fkjhwojfw","192.168.4.4.4","2620:3","2620::33"]

for test in tests {
    if let _ = IPv4Address(test) {
        debugPrint("\(test) is valid ipv4 address")
    } else if let _ = IPv6Address(test) {
        debugPrint("\(test) is valid ipv6 address")
    } else {
        debugPrint("\(test) is not a valid IP address")
    }
}

output:
"192.168.4.4 is valid ipv4 address"
"fkjhwojfw is not a valid IP address"
"192.168.4.4.4 is not a valid IP address"
"2620:3 is not a valid IP address"
"2620::33 is valid ipv6 address"
0
Darrell R

Saya menemukan ini berfungsi dengan baik untuk alamat IP. Ini memvalidasi seperti jawaban teratas tetapi juga memastikan ip diisolasi sehingga tidak ada teks atau lebih banyak angka/desimal setelah atau sebelum ip.

(? <!\S) (?: (?:\D | [1-9]\d | 1\d\d | 2 [0-4]\d | 25 [0-5])\b |.\b) {7} (?!\S)

0
Andrew
>>> my_hostname = "testhostn.ame"
>>> print bool(re.match("^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$", my_hostname))
True
>>> my_hostname = "testhostn....ame"
>>> print bool(re.match("^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$", my_hostname))
False
>>> my_hostname = "testhostn.A.ame"
>>> print bool(re.match("^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$", my_hostname))
True

Mengenai alamat IP, tampaknya ada beberapa perdebatan tentang apakah akan memasukkan angka nol di depan. Itu dulunya praktik umum dan diterima secara umum, jadi saya berpendapat bahwa mereka harus ditandai sebagai valid terlepas dari preferensi saat ini. Ada juga beberapa ambiguitas tentang apakah teks sebelum dan sesudah string harus divalidasi dan, sekali lagi, saya pikir seharusnya. 1.2.3.4 adalah IP yang valid tetapi 1.2.3.4.5 tidak dan bagian 1.2.3.4 atau 2.3.4.5 tidak menghasilkan pertandingan. Beberapa masalah dapat ditangani dengan ungkapan ini:

grep -E '(^|[^[:alnum:]+)(([0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.){3}([0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])([^[:alnum:]]|$)' 

Bagian yang disayangkan di sini adalah kenyataan bahwa bagian regex yang memvalidasi oktet diulangi seperti yang terjadi pada banyak solusi yang ditawarkan. Meskipun ini lebih baik daripada untuk contoh pola, pengulangan dapat dihilangkan seluruhnya jika subrutin didukung dalam regex yang digunakan. Contoh berikutnya memungkinkan fungsi-fungsi tersebut dengan -P switch grep dan juga memanfaatkan fungsi lookahead dan lookbehind. (Nama fungsi yang saya pilih adalah 'o' untuk oktet. Saya bisa menggunakan 'oktet' sebagai nama tetapi ingin singkat.)

grep -P '(?<![\d\w\.])(?<o>([0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]))(\.\g<o>){3}(?![\d\w\.])'

Penanganan titik sebenarnya bisa membuat negatif palsu jika alamat IP dalam file dengan teks dalam bentuk kalimat karena periode dapat mengikuti tanpa menjadi bagian dari notasi bertitik. Varian di atas akan memperbaikinya:

grep -P '(?<![\d\w\.])(?<x>([0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]))(\.\g<x>){3}(?!([\d\w]|\.\d))'
0
Thom Anderson

Berikut adalah regex yang saya gunakan di Ant untuk mendapatkan IP Host proxy atau nama host dari ANT_OPTS. Ini digunakan untuk mendapatkan IP proxy sehingga saya bisa menjalankan tes "isreachable" Ant sebelum mengkonfigurasi proxy untuk JVM bercabang dua.

^.*-Dhttp\.proxyHost=(\w{1,}\.\w{1,}\.\w{1,}\.*\w{0,})\s.*$
0
Bill Stephens

coba ini:

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

itu berfungsi dalam kasus saya.

0
seraphim
AddressRegex = "^(ftp|http|https):\/\/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:[0-9]{1,5})$";

HostnameRegex =  /^(ftp|http|https):\/\/([a-z0-9]+\.)?[a-z0-9][a-z0-9-]*((\.[a-z]{2,6})|(\.[a-z]{2,6})(\.[a-z]{2,6}))$/i

ini digunakan hanya untuk validasi tipe ini

hanya berfungsi jika http://www.kk.comhttp://www.kk.co .in

tidak berfungsi untuk

http://www.kk.com/http: //www.kk.co.in.kk

http://www.kk.com/dfashttp://www.kk.co.in/

0
ayu for u