Biểu thức chính quy sẽ khớp với tên miền hợp lệ mà không có miền phụ là gì?


123

Tôi cần xác thực tên miền:

google.com

stackoverflow.com

Vì vậy, một miền ở dạng thô nhất của nó - thậm chí không phải là một miền phụ như www.

  1. Các ký tự chỉ nên az | AZ | 0-9thời gian (.) Và dấu gạch ngang (-)
  2. Phần tên miền không được bắt đầu hoặc kết thúc bằng dấu gạch ngang (-) (ví dụ -google-.com)
  3. Phần tên miền phải dài từ 1 đến 63 ký tự
  4. Tiện ích mở rộng (TLD) hiện tại có thể là bất kỳ thứ gì theo quy tắc số 1, tôi có thể xác thực chúng dựa trên danh sách sau này, mặc dù vậy, nó phải có 1 hoặc nhiều ký tự

Chỉnh sửa: TLD rõ ràng là 2-6 ký tự như nó viết tắt

Không. 4 sửa đổi: TLD thực sự nên được gắn nhãn "tên miền phụ" vì nó phải bao gồm những thứ như .co.uk - Tôi sẽ tưởng tượng cách xác thực duy nhất có thể (ngoài việc kiểm tra đối với danh sách) sẽ là 'sau dấu chấm đầu tiên phải có một hoặc nhiều ký tự hơn theo quy tắc số 1

Cảm ơn rất nhiều, tin rằng tôi đã cố gắng!


1
Có thể không hữu ích ở tất cả. Khi nói đến google.co.uk và một số tên miền Nhật Bản, tôi chắc chắn rằng bạn sẽ phải suy nghĩ kỹ trước khi sử dụng regex cho điều đó. Suy nghĩ cá nhân của tôi là regex không đủ để xác thực miền thành miền ngoài đời thực. FYI, đây là một danh sách gần như hoàn chỉnh các tên miền cấp cao mã quốc gia và danh sách tên miền cấp thứ hai: static.ayesh.me/misc/SO/tlds.txt
Ayesh K

1
Xem câu trả lời của tôi cho câu hỏi liên quan về xác thực tên máy chủ .
SAM

2
Thường bị quên: Đối với các tên miền đủ điều kiện, bạn nên khớp một dấu chấm sau chữ tld.
schmijos

1
nó được 4 năm, bây giờ số lượng lên đến 89.000
mydoglixu

1
Một số câu trả lời trong số này khá hay, nhưng cũng có một câu trả lời hay khác cho câu hỏi này đáng xem.
craftworkgames

Câu trả lời:


49

Chà, nó khá đơn giản, lén lút hơn một chút so với vẻ ngoài (xem nhận xét), với các yêu cầu cụ thể của bạn:

/^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}$/

Nhưng lưu ý rằng điều này sẽ từ chối rất nhiều tên miền hợp lệ.


Rất cảm ơn cái này có vẻ đang hoạt động. Bạn biết loại miền nào sẽ không vượt qua xác thực?
Dominic

12
@infensus - Mặc dù regex này đúng với thông số kỹ thuật của bạn, nhưng thông số kỹ thuật của bạn lại sai. g.colà một tên miền hợp lệ nhưng gchỉ có một ký tự.
sch

3
Điều này sẽ phù hợp với tất cả các trường hợp mà tôi nghĩ: ^ ([a-z0-9]) (([a-z0-9 -] {1,61})? [A-z0-9] {1})? (\. [a-z0-9] (([a-z0-9 -] {1,61})? [a-z0-9] {1})?)? (\. [a-zA-Z] {2 , 4}) + $
transilvlad

1
x.com sẽ không vượt qua ở đây
Neil McGuigan

4
@Neil: Bạn nói đúng. Câu hỏi ban đầu yêu cầu 3-63 ký tự (xem chỉnh sửa 3). Nó có thể được thay đổi để hỗ trợ các lĩnh vực một nhân vật khá dễ dàng: /^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.[a-zA-Z]{2,}$/. Nhưng điều này vẫn từ chối hàng tấn nội dung hợp lệ ...
Cameron

85

Tôi biết rằng đây là một bài viết hơi cũ, nhưng tất cả các cụm từ thông dụng ở đây đều thiếu một thành phần rất quan trọng: hỗ trợ cho tên miền IDN.

Tên miền IDN bắt đầu bằng xn--. Chúng cho phép các ký tự UTF-8 mở rộng trong tên miền. Ví dụ: bạn có biết "♡ .com" là một tên miền hợp lệ không? Yeah, "love heart dot com"! Để xác thực tên miền, bạn cần để http://xn--c6h.com/ vượt qua quá trình xác thực.

Lưu ý, để sử dụng regex này, bạn sẽ cần phải chuyển đổi tên miền thành chữ thường và cũng sử dụng thư viện IDN để đảm bảo bạn mã hóa tên miền thành ACE (còn được gọi là "Mã hóa tương thích ASCII"). Một thư viện tốt là GNU-Libidn.

idn (1) là giao diện dòng lệnh đến thư viện tên miền quốc tế. Ví dụ sau chuyển đổi tên máy chủ trong UTF-8 thành mã hóa ACE. Sau đó, URL kết quả https: //nic.xn--flw351e/ sau đó có thể được sử dụng làm tương đương được mã hóa ACE của https: // nic. 谷 歌 / .

  $ idn --quiet -a nic.谷歌
  nic.xn--flw351e

Biểu thức chính quy ma thuật này sẽ bao gồm hầu hết các miền (mặc dù, tôi chắc chắn rằng có nhiều trường hợp cạnh hợp lệ mà tôi đã bỏ qua):

^((?!-))(xn--)?[a-z0-9][a-z0-9-_]{0,61}[a-z0-9]{0,1}\.(xn--)?([a-z0-9\-]{1,61}|[a-z0-9-]{1,30}\.[a-z]{2,})$

Khi chọn regex xác thực tên miền, bạn nên xem tên miền có khớp với những điều sau đây không:

  1. xn--stackoverflow.com
  2. stackoverflow.xn - com
  3. stackoverflow.co.uk

Nếu ba miền này không vượt qua, biểu thức chính quy của bạn có thể không cho phép các miền hợp pháp!

Hãy xem trang Hỗ trợ Tên miền Quốc tế hóa từ Hướng dẫn Môi trường Ngôn ngữ Quốc tế của Oracle để biết thêm thông tin.

Vui lòng dùng thử regex tại đây: http://www.regexr.com/3abjr

ICANN lưu giữ danh sách các tld đã được ủy quyền có thể được sử dụng để xem một số ví dụ về miền IDN.


Biên tập:

 ^(((?!-))(xn--|_{1,1})?[a-z0-9-]{0,61}[a-z0-9]{1,1}\.)*(xn--)?([a-z0-9][a-z0-9\-]{0,60}|[a-z0-9-]{1,30}\.[a-z]{2,})$

Cụm từ thông dụng này sẽ ngăn các miền có dấu '-' ở cuối tên máy chủ được đánh dấu là hợp lệ. Ngoài ra, nó cho phép các miền phụ không giới hạn.


1
Lưu ý rằng điều này sẽ chỉ hỗ trợ tối đa một tên miền phụ, bất cứ điều gì nhiều hơn điều đó sẽ dẫn đến sai. Đó không phải là một cái gì đó mà bạn đang phỉ báng chạy vào trừ khi sử dụng nó cho các trang web nội bộ, vv ... Một nỗ lực nhanh chóng để cho phép nó hỗ trợ nhiều tên miền phụ:/^((?!-))(xn--)?[a-z0-9][a-z0-9-_]{0,61}[a-z0-9]{0,}\.?((xn--)?([a-z0-9\-.]{1,61}|[a-z0-9-]{1,30})\.?[a-z]{2,})$/i
stakolee

1
Nhưng các tld cô đơn không hoạt động :( Ví dụ: to.( to. ) Là url hợp lệ có nội dung.
iiic 16/09/16

@iiic, có, nhưng to.không phải là một tên miền hoàn toàn đủ điều kiện. Nếu bạn muốn cho phép các tên miền cấp cao nhất, thì bạn nên sử dụng một cái gì đó như ^(((?!-))(xn--)?[a-z0-9][a-z0-9-_]{0,61}[a-z0-9]{0,1}\.)?(x--)?([a-z0-9\-]{1,61}|[a-z0-9-]{1,30}\.[a-z]{2,})\.?$, nhưng được cảnh báo, bạn sẽ cho phép những người đặt tên miền như testhoặc na, quá!
Tim Groeneveld

Nó chấp nhận invali.dlà một tên miền hợp lệ trong khi invali.d.co.ukkhông hợp lệ.
Pawel Krakowiak

1
Cần lưu ý rằng đó xn--stackoverflow.comkhông phải là tên hợp lệ vì 'stackoverflow' không thể được chuyển đổi từ Punycode. Tuy nhiên, điều đó vượt quá những gì regex có thể làm. Như một nhận xét chung, xn--[a-z0-9]+các nhãn sẽ chỉ có IDN trong khi xn--[a-z0-9]+\-[a-z0-9]+biểu thị sự kết hợp của các ký tự ASCII và không phải ASCII
Marcus

50

RegEx của tôi là tiếp theo:

^[a-zA-Z0-9][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}\.([a-zA-Z]{1,6}|[a-zA-Z0-9-]{1,30}\.[a-zA-Z]{2,3})$

nó ổn cho i.oh1.me và cho wow.british-library.uk

UPD

Đây là quy tắc cập nhật

^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$

Hình ảnh hóa biểu thức chính quy

https://www.debuggex.com/r/y4Xe_hDVO11bv1DV

bây giờ nó kiểm tra -hoặc _ở phần đầu hoặc phần cuối của nhãn tên miền.


9
Trông khá ổn, nhưng các {2,6}tiêu chí sẽ cần được cập nhật cho TLD mới. Có lẽ {2,}.
jwatts1980 Ngày

@ jwatts1980 có ví dụ về các khu như vậy không? hoặc bạn có nghĩa là cho các khu vực có thể trong tương lai?
paka

1
Dưới đây là một bài viết thảo luận những thay đổi sắp tới với các ví dụ và các liên kết đến các tài nguyên liên quan: zdnet.com/...
jwatts1980

1
Tại sao ([a-zA-Z] {1} [a-zA-Z] {1}) mà không phải ([a-zA-Z] {2})?
Anton

3
Phần cuối cùng với hai lựa chọn thay thế cũng sai: tồn tại ccTLD (hai chữ cái) chấp nhận nhãn phụ IDNA. Hiện cũng có các nhãn TLD đã sử dụng nhãn IDNA. Bạn không nên viết hoa chữ thường nhãn cuối cùng không khác với những nhãn khác (và bây giờ có nhiều phần mở rộng được thêm vào với độ dài thay đổi, jsut giống như tất cả các nhãn khác trong tên miền phụ. Lưu ý rằng các nhãn IDNA cũng có thể xuất hiện Punycoded (trong trường hợp đó sẽ có "- - "một phân đoạn trong nhãn, trường hợp duy nhất cho phép" - "trong nhãn .. Cuối cùng, dấu gạch dưới không hợp lệ ở mọi nơi trong tất cả các nhãn.
verdy_p

24

Đặt cược của tôi:

^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]$

Giải thích:

Tên miền được xây dựng từ các phân đoạn. Đây là một phân đoạn (ngoại trừ cuối cùng):

[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?

Nó có thể có 1-63 ký tự, không bắt đầu hoặc kết thúc bằng '-'.

Bây giờ hãy nối '.' với nó và lặp lại ít nhất một lần:

(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+

Sau đó, đính kèm phân đoạn cuối cùng, dài từ 2-63 ký tự:

[a-z0-9][a-z0-9-]{0,61}[a-z0-9]

Kiểm tra nó ở đây: http://regexr.com/3au3g


@GaneshBabu Bạn có ý nghĩa gì về kết quả chính xác?
Yaroslav Stavnichiy 15/12/16

1
Tất cả các câu trả lời khác không phù hợp với tôi nhưng câu trả lời này thì có.
Danny Coulombe

Tôi đã có một yêu cầu tương tự trong đó tôi muốn tránh dấu chấm phẩy và dấu phẩy ở cuối, tôi đã thử rất nhiều nhưng không thành công. Dưới đây là Regex mà tôi đang sử dụng const regexDomain = / ^ (?: [A-Za-z0-9] (?: [A-Za-z0-9 -] {0,61} [A-Za-z0-9])? \.) + [A-Za-z0-9] [A-Za-z0-9 -] { 0,61} [A-Za-z0-9] / g; Nó xác nhận nếu tôi sử dụng, và; ở giữa nhưng không thành công khi kết thúc.
Harry

Tôi đã tìm thấy một số tên miền phải hợp lệ nhưng không hợp lệ với regex của bạn. Ví dụ редбулл.москва là một tên miền hợp lệ hoặc cũng редбулл.рф và红色的公牛中国.
pubkey

1
@pubkey, bạn cần chuyển đổi các tên miền đó sang punycode . Tên thực của редбулл.москва là xn - 90afc0aazy.xn - 80adxhks Và regex của tôi khớp với nó.
Yaroslav Stavnichiy

13

Chỉ là một chỉnh sửa nhỏ - phần cuối cùng phải lên đến 6. Do đó,

^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,6}$

TLD dài nhất là museum(6 ký tự) - http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains


3
Lưu ý: Điều này sẽ không vượt qua được (chưa hiếm) tên hợp lệ miền www.my---domain.com
Chris Bier

17
Không cắt nó với TLD mới, ví dụ.photography
Sam Figueroa.

2
@SamFigueroa Bạn sẽ chỉ phải thay đổi chiều dài của nó
Thép Brain

3
không nên kiểm tra TLD nó không khác với các miền phụ. Và dựa trên regex trên các availabletld hiện tại không phải là bằng chứng trong tương lai.
Loïc Faure-Lacroix

1
Đề xuất bit cuối cùng là {2,63}: xem stackoverflow.com/questions/9238640/…
Eric Dobbs

13

Câu trả lời được chấp nhận không hoạt động với tôi, hãy thử điều này:

^ ((?! -) [A-Za-z0-9 -] {1,63} (? <! -) \.) + [A-Za-z] {2,6} $

Truy cập các Trường hợp Kiểm tra Đơn vị này để xác nhận.


4
không hỗ trợ các tên TLD mới dài hơn như .audio, .photography và hầu hết các tên này ... data.iana.org/TLD/tlds-alpha-by-domain.txt
mrbinky3000 15/04/15

@ mrbinky3000 Chỉ cần thay đổi cuối cùng {2,6}thành thứ khác và nó sẽ hoạt động. Của tôi:^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+(?!-)[a-zA-Z0-9-]{1,63}(?<!-)$
Mygod

@Mygod regex của bạn có chứa một số zero width rác quá khứ dấu hỏi cuối cùng, vì vậy bất cứ ai sao chép nó sẽ ngạc nhiên khó chịu
MightyPork

1
@MightyPork Bạn nói đúng! Xin lỗi, đây là phiên bản sạch (hy vọng):^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+(?!-)[a-zA-Z0-9-]{1,63}(?<!-)$
Mygod

Rất đẹp. Than ôi, biểu thức lookbehind không hợp lệ trong JavaScript. : /
PhiLho

13

Câu trả lời này dành cho tên miền (bao gồm RR của dịch vụ), không phải tên máy chủ (như tên máy chủ email).

^(?=.{1,253}\.?$)(?:(?!-|[^.]+_)[A-Za-z0-9-_]{1,63}(?<!-)(?:\.|$)){2,}$

Về cơ bản đó là câu trả lời của mkyong và thêm vào đó:

  • Độ dài tối đa là 255 octet bao gồm tiền tố độ dài và gốc rỗng.
  • Cho phép dấu '.' cho gốc dns rõ ràng.
  • Cho phép '_' đứng đầu đối với RR của miền dịch vụ, (lỗi: không thực thi tối đa 15 ký tự cho nhãn _, cũng như không yêu cầu ít nhất một miền trên RR của dịch vụ)
  • Đối sánh tất cả các TLD có thể có.
  • Không nắm bắt nhãn miền phụ.

Theo bộ phận

Nhìn trước, giới hạn độ dài tối đa trong khoảng từ ^ $ đến 253 ký tự với ký tự ở cuối tùy chọn '.'

(?=.{1,253}\.?$)

Nhìn trước, ký tự tiếp theo không phải là '-' và không có '_' theo sau bất kỳ ký tự nào trước ký tự tiếp theo '.'. Có nghĩa là, hãy thực thi rằng ký tự đầu tiên của nhãn không phải là '-' và chỉ ký tự đầu tiên có thể là '_'.

(?!-|[^.]+_)

Từ 1 đến 63 ký tự được phép trên mỗi nhãn.

[A-Za-z0-9-_]{1,63}

Nhìn sau, ký tự trước không phải là '-'. Có nghĩa là, hãy thực thi rằng ký tự cuối cùng của nhãn không phải là '-'.

(?<!-)

Buộc một '.' ở cuối mỗi nhãn ngoại trừ nhãn cuối cùng, nơi nó là tùy chọn.

(?:\.|$)

Chủ yếu được kết hợp từ phía trên, điều này yêu cầu ít nhất hai cấp miền, điều này không hoàn toàn chính xác, nhưng thường là một giả định hợp lý. Thay đổi từ {2,} thành + nếu bạn muốn cho phép TLD hoặc tên miền phụ tương đối không đủ tiêu chuẩn thông qua (ví dụ: localhost, myrouter, to.)

(?:(?!-|[^.]+_)[A-Za-z0-9-_]{1,63}(?<!-)(?:\.|$)){2,}

Kiểm tra đơn vị cho biểu thức này.


1
Cảm ơn! Đây là regex tốt nhất ở đây. Giải thích cặn kẽ của bạn và bài kiểm tra đơn vị là một phần thưởng
naudster

"RR" có nghĩa là gì?
bánh xe

Bản ghi tài nguyên. Thường là trường văn bản hoặc trường thông tin cho bạn biết cách tương tác với một dịch vụ.
Andrew Domaszek

Regex này không đúng. Ví dụ: miền redbull. 移动 hợp lệ nhưng regex sẽ không khớp.
pubkey

Chuyển đổi sang punycode trước, sau đó khớp. Giới hạn độ dài trên phiên bản tiền punycode thực sự khó thực hiện.
Andrew Domaszek

8

Cảm ơn bạn đã chỉ ra đúng hướng trong các giải pháp xác thực tên miền trong các câu trả lời khác. Tên miền có thể được xác nhận theo nhiều cách khác nhau.

Nếu bạn cần xác thực miền IDN ở dạng con người có thể đọc được , regex \p{L}sẽ giúp bạn. Điều này cho phép khớp bất kỳ ký tự nào trong bất kỳ ngôn ngữ nào.

Lưu ý rằng phần cuối cũng có thể chứa dấu gạch nối ! Vì tên tiếng Chine được mã hóa punycode có thể có các ký tự unicode trong tld.

Tôi đã đi đến giải pháp phù hợp với ví dụ:

  • google.com
  • masełkowski.pl
  • maselkowski.pl
  • m.maselkowski.pl
  • www.masełkowski.pl.com
  • xn--masekowski-d0b.pl
  • 中国 互联 网络 信息 中心. 中国
  • xn - fiqa61au8b7zsevnm8ak20mc4a87e.xn - fiqs8s

Regex là:

^[0-9\p{L}][0-9\p{L}-\.]{1,61}[0-9\p{L}]\.[0-9\p{L}][\p{L}-]*[0-9\p{L}]+$

Kiểm tra và điều chỉnh tại đây

LƯU Ý: Regexp này khá dễ dãi, cũng như bộ ký tự cho phép tên miền hiện tại.

CẬP NHẬT : Đơn giản hơn nữa, a-aA-Z\p{L}giống như chỉ\p{L}

LƯU Ý 2: Vấn đề duy nhất là nó sẽ khớp với các miền có dấu chấm kép trong đó ..., như masełk..owski.pl. Nếu ai biết cách sửa lỗi này, xin vui lòng cải thiện.


Chúng ta chỉ có thể sử dụng [:alpha:][:digit]thay thế \p{L}. Nó hoạt động tốt.
puchu

Bạn không thể xác thực IDN theo cách này mà không chuyển đổi nó thành punycode trước. Ví dụ: với expr của bạn, 中国互联网络信息中心中国互联网络信息中心中国互联网络信.中国kiểm tra là hợp lệ, nhưng sau khi chuyển đổi IDN, nó có quá nhiều byte cho mỗi nhãn. \ p {L} đối sánh với các biểu tượng, không phải byte punycode (thay đổi tùy theo từng biểu tượng), do đó, số lần lặp lại không hữu ích khi cố gắng giới hạn kích thước sau chuyển đổi của nó.
Andrew Domaszek

Điểm tốt, mỗi phần được giới hạn trong 64 byte. Tuy nhiên, chúng tôi không thể kiểm tra nó bằng RegExp, vì vậy cần có các bước xác thực thêm bằng bộ giải mã punycode - sẽ không thành công với tên máy chủ mẫu của bạn. Người chineese phải phát điên vì hạn chế này.
PeterM

7
^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,7}$

[tên miền - chỉ các chữ cái viết thường và 0-9] [có thể có dấu gạch ngang] + [TLD - chỉ chữ thường, phải dài từ 2 đến 7 chữ cái]
http://rubular.com/ rất tuyệt vời để kiểm tra cụm từ thông dụng!
Chỉnh sửa: Đã cập nhật TLD tối đa thành 7 ký tự cho '.rentals' như Dan Caddigan đã chỉ ra.


1
Tại sao giới hạn TLD? Bây giờ .photographysẽ không hợp lệ. Chỉ cần làm cho nó ký tự không giới hạn hoặc những thứ tương tự.
adriaan

5

Chưa đủ đại diện để bình luận. Để đáp lại giải pháp của paka, tôi thấy mình cần điều chỉnh ba mục:

  • Dấu gạch ngang và dấu gạch dưới đã được di chuyển do dấu gạch ngang được hiểu là một phạm vi (như trong "0-9")
  • Đã thêm một điểm dừng đầy đủ cho các tên miền có nhiều tên miền phụ
  • Mở rộng độ dài tiềm năng cho TLD lên 13

Trước:

^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$

Sau:

^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][-_\.a-zA-Z0-9]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,13}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$

3

Đối với gTLD mới

/^((?!-)[\p{L}\p{N}-]+(?<!-)\.)+[\p{L}\p{N}]{2,}$/iu

2
Vui lòng cho chúng tôi biết thêm một số thông tin chi tiết mà bạn trả lời có làm tốt hơn những câu khác không? Bạn phù hợp hơn với điều gì? Vui lòng chỉnh sửa trực tiếp bài viết của bạn để thêm thông tin.
Sven R.

Giống như tôi đã viết: gTLDs mới. Miền có ký tự unicode và cả TLD unicode.
Ben Keil,

1
@BenKeil: Phần này nói về cái gì vậy: (? <! -)
jor

@jor đó là cái nhìn tiêu cực đằng sau. Hãy xem điều này qua shortcutfoo.com/app/dojos/regex/cheatsheet
Muhammad Faizan,

3

Như đã chỉ ra, không rõ ràng khi nói tên miền phụ theo nghĩa thực tế (ví dụ: .co.uktên miền). Chúng tôi sử dụng regex này để xác thực các miền xảy ra trong tự nhiên. Nó bao gồm tất cả các trường hợp sử dụng thực tế mà tôi biết. Những cái mới được chào đón. Theo nguyên tắc của chúng tôi, nó tránh các nhóm không nắm bắt và đối sánh tham lam.

^(?!.*?_.*?)(?!(?:[\d\w]+?\.)?\-[\w\d\.\-]*?)(?![\w\d]+?\-\.(?:[\d\w\.\-]+?))(?=[\w\d])(?=[\w\d\.\-]*?\.+[\w\d\.\-]*?)(?![\w\d\.\-]{254})(?!(?:\.?[\w\d\-\.]*?[\w\d\-]{64,}\.)+?)[\w\d\.\-]+?(?<![\w\d\-\.]*?\.[\d]+?)(?<=[\w\d\-]{2,})(?<![\w\d\-]{25})$

Bằng chứng, giải thích và ví dụ: https://regex101.com/r/FLA9Bv/9 ( Lưu ý: hiện chỉ hoạt động trong Chrome vì regex sử dụng giao diện chỉ được hỗ trợ trong ECMA2018 )

Có hai phương pháp để lựa chọn khi xác thực miền.

Đối sánh FQDN theo sách (định nghĩa lý thuyết, hiếm khi gặp trong thực tế):

  • độ dài tối đa 253 ký tự (theo RFC-1035 / 3.1 , RFC-2181/11 )
  • độ dài tối đa 63 ký tự trên mỗi nhãn (theo RFC-1035 / 3.1 , RFC-2181/11 )
  • bất kỳ ký tự nào được phép (theo RFC-2181/11 )
  • TLD không được toàn số (theo RFC-3696/2 )
  • FQDNs có thể được viết ở dạng hoàn chỉnh, bao gồm vùng gốc (dấu chấm)

Đối sánh FQDN thực tế / bảo thủ (định nghĩa thực tế, được mong đợi và hỗ trợ trong thực tế):

  • phù hợp với sách phụ với các ngoại lệ / bổ sung sau
  • ký tự hợp lệ: [a-zA-Z0-9.-]
  • nhãn không thể bắt đầu hoặc kết thúc bằng dấu gạch nối (theo RFC-952RFC-1123 / 2.1 )
  • Độ dài tối thiểu TLD là 2 ký tự, độ dài tối đa là 24 ký tự theo các bản ghi hiện có
  • không khớp với dấu chấm ở cuối


2

Đây là mã hoàn chỉnh với ví dụ:

<?php
function is_domain($url)
{
    $parse = parse_url($url);
    if (isset($parse['host'])) {
        $domain = $parse['host'];
    } else {
        $domain = $url;
    }

    return preg_match('/^(?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63}$/', $domain);
}

echo is_domain('example.com'); //true
echo is_domain('https://example.com'); //true
echo is_domain('https://.example.com'); //false
echo is_domain('https://localhost'); //false

2
^((localhost)|((?!-)[A-Za-z0-9-]{1,63}(?<!-)\.)+[A-Za-z]{2,253})$

Cảm ơn bạn @mkyong về cơ sở cho câu trả lời của tôi. Tôi đã sửa đổi nó để hỗ trợ các nhãn dài hơn được chấp nhận.

Ngoài ra, "localhost" về mặt kỹ thuật là một tên miền hợp lệ. Tôi sẽ sửa đổi câu trả lời này để phù hợp với các tên miền được quốc tế hóa.


0
/^((([a-zA-Z]{1,2})|([0-9]{1,2})|([a-zA-Z0-9]{1,2})|([a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]))\.)+[a-zA-Z]{2,6}$/
  • ([a-zA-Z]{1,2}) -> chỉ chấp nhận hai ký tự.

  • ([0-9]{1,2})-> chỉ chấp nhận hai số

nếu bất cứ điều gì vượt quá hai ([a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]), regex này sẽ xử lý điều đó.

Nếu chúng ta muốn thực hiện kết hợp ít nhất một lần +sẽ được sử dụng.


0

^ [a-zA-Z0-9] [- a-zA-Z0-9] + [a-zA-Z0-9]. [az] {2,3} (. [az] {2,3}) ? (. [az] {2,3})? $

Các ví dụ hoạt động:

stack.com
sta-ck.com
sta---ck.com
9sta--ck.com
sta--ck9.com
stack99.com
99stack.com
sta99ck.com

Nó cũng sẽ hoạt động cho các phần mở rộng

.com.uk
.co.in
.uk.edu.in

Các ví dụ sẽ không hoạt động:

-stack.com

nó sẽ hoạt động ngay cả với phần mở rộng tên miền dài nhất ".versicherung"



0

Regex sau đây trích xuất con, gốc và tld của một miền nhất định:

^(?<domain>(?<domain_sub>(?:[^\/\"\]:\.\s\|\-][^\/\"\]:\.\s\|]*?\.)*?)(?<domain_root>[^\/\"\]:\s\.\|\n]+\.(?<domain_tld>(?:xn--)?[\w-]{2,7}(?:\.[a-zA-Z-]{2,3})*)))$

Đã kiểm tra các miền sau:

* stack.com
* sta-ck.com
* sta---ck.com
* 9sta--ck.com
* sta--ck9.com
* stack99.com
* 99stack.com
* sta99ck.com
* google.com.uk
* google.co.in

* google.com
* masełkowski.pl
* maselkowski.pl
* m.maselkowski.pl
* www.masełkowski.pl.com
* xn--masekowski-d0b.pl
* xn--fiqa61au8b7zsevnm8ak20mc4a87e.xn--fiqs8s

* xn--stackoverflow.com
* stackoverflow.xn--com
* stackoverflow.co.uk

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.