นิพจน์ทั่วไปที่จะจับคู่ชื่อโดเมนที่ถูกต้องโดยไม่มีโดเมนย่อยคืออะไร


123

ฉันต้องการตรวจสอบชื่อโดเมน:

google.com

stackoverflow.com

ดังนั้นโดเมนในรูปแบบที่ดิบที่สุดไม่ใช่แม้แต่โดเมนย่อยเช่น www

  1. อักขระควรเป็นaz | AZ | 0-9และระยะเวลา (.) และขีด (-)
  2. ส่วนของชื่อโดเมนไม่ควรขึ้นต้นหรือลงท้ายด้วยเครื่องหมายขีด (-) (เช่น -google-.com)
  3. ส่วนของชื่อโดเมนควรมีความยาวระหว่าง 1 ถึง 63 อักขระ
  4. ส่วนขยาย (TLD) อาจเป็นอะไรก็ได้ภายใต้กฎ # 1 ในตอนนี้ฉันสามารถตรวจสอบความถูกต้องกับรายการในภายหลังได้ แต่ควรมี 1 อักขระขึ้นไป

แก้ไข: TLD เห็นได้ชัดว่าเป็น 2-6 ตัวอักษรตามที่ระบุ

ไม่ แก้ไข 4 ครั้ง: TLD ควรมีป้ายกำกับว่า "โดเมนย่อย" ตามที่ควรมีเช่น. co.uk - ฉันคิดว่าการตรวจสอบความถูกต้องเดียวที่เป็นไปได้ (นอกเหนือจากการตรวจสอบกับรายการ) จะเป็น "หลังจากจุดแรกควรมีอย่างใดอย่างหนึ่งหรือ อักขระเพิ่มเติมภายใต้กฎ # 1

ขอบคุณมากเชื่อฉันฉันได้ลอง!


1
อาจไม่เป็นประโยชน์เลย เมื่อพูดถึง google.co.uk และโดเมนภาษาญี่ปุ่นบางโดเมนฉันแน่ใจว่าคุณจะต้องคิดให้ดีก่อนที่จะใช้ regex ความคิดส่วนตัวของฉันคือ regex ไม่เพียงพอที่จะตรวจสอบโดเมนกับโดเมนในชีวิตจริง FYI นี่คือรายการโดเมนระดับที่สองของ tlds และรหัสประเทศเกือบทั้งหมด: static.ayesh.me/misc/SO/tlds.txt
Ayesh K

1
ดูคำตอบของฉันไปที่คำถามที่เกี่ยวข้องเกี่ยวกับการตรวจสอบชื่อโฮสต์
SAM

2
มักถูกลืม: สำหรับชื่อโดเมนแบบเต็มคุณควรจับคู่ช่วงเวลาหลัง tld
schmijos

1
เป็นเวลา 4 ปีแล้วตอนนี้นับได้ถึง 89,000
mydoglixu

1
คำตอบเหล่านี้บางคำค่อนข้างดี แต่ก็มีอีกคำตอบที่ดีสำหรับคำถามอื่น ๆที่น่าดู
craftworkgames

คำตอบ:


50

มันค่อนข้างตรงไปตรงมาแอบแฝงกว่าที่คิดเล็กน้อย (ดูความคิดเห็น) ตามข้อกำหนดเฉพาะของคุณ:

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

แต่โปรดทราบว่านี่จะปฏิเสธโดเมนที่ถูกต้องจำนวนมาก


ดีขอบคุณที่ดูเหมือนจะใช้งานได้ คุณทราบโดเมนประเภทใดบ้างที่ไม่ผ่านการตรวจสอบความถูกต้อง
Dominic

12
@infensus - แม้ว่า regex นี้จะถูกต้องตามข้อกำหนดของคุณ แต่ข้อกำหนดของคุณก็ไม่ถูกต้อง g.coเป็นชื่อโดเมนที่ถูกต้อง แต่gเป็นเพียงอักขระเดียว
sch

3
สิ่งนี้ควรตรงกับทุกกรณีที่ฉันคิด: ^ ([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 จะไม่ผ่านที่นี่
Neil McGuigan

4
@ นีล: คุณพูดถูก คำถามเดิมถามเป็นอักขระ 3-63 ตัว (ดูแก้ไข 3) /^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.[a-zA-Z]{2,}$/มันสามารถเปลี่ยนเป็นสนับสนุนโดเมนหนึ่งอักขระธรรมได้อย่างง่ายดาย: แต่สิ่งนี้ยังคงปฏิเสธสิ่งที่ถูกต้องมากมาย ...
คาเมรอน

85

ฉันรู้ว่านี่เป็นบทความเก่า แต่นิพจน์ทั่วไปทั้งหมดที่นี่ขาดองค์ประกอบที่สำคัญอย่างหนึ่งนั่นคือการรองรับชื่อโดเมน IDN

ชื่อโดเมน IDNขึ้นต้นด้วย xn--. เปิดใช้งานอักขระ UTF-8 แบบขยายในชื่อโดเมน ตัวอย่างเช่นคุณทราบหรือไม่ว่า "♡ .com" เป็นชื่อโดเมนที่ถูกต้อง เย้ "ใจรักดอทคอม"! ในการตรวจสอบชื่อโดเมนคุณต้องปล่อยให้http://xn--c6h.com/ผ่านการตรวจสอบความถูกต้อง

หมายเหตุในการใช้ regex นี้คุณจะต้องแปลงโดเมนเป็นตัวพิมพ์เล็กและใช้ไลบรารี IDN เพื่อให้แน่ใจว่าคุณได้เข้ารหัสชื่อโดเมนเป็น ACE (หรือเรียกว่า "ASCII Compatible Encoding") ห้องสมุดที่ดีอย่างหนึ่งคือ GNU-Libidn

idn (1) คืออินเทอร์เฟซบรรทัดคำสั่งไปยังไลบรารีชื่อโดเมนสากล ตัวอย่างต่อไปนี้แปลงชื่อโฮสต์ใน UTF-8 เป็นการเข้ารหัส ACE URL ของhttps: //nic.xn--flw351e/แล้วสามารถใช้เป็น ACE เข้ารหัสเทียบเท่าhttps: //. NIC谷歌 /

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

การแสดงออกปกติของเวทมนตร์นี้ควรครอบคลุมโดเมนส่วนใหญ่ (แม้ว่าฉันแน่ใจว่ามีขอบที่ถูกต้องหลายกรณีที่ฉันพลาดไป):

^((?!-))(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,})$

เมื่อเลือก regex การตรวจสอบโดเมนคุณควรดูว่าโดเมนตรงกับสิ่งต่อไปนี้หรือไม่:

  1. xn--stackoverflow.com
  2. stackoverflow.xn - คอม
  3. stackoverflow.co.uk

หากโดเมนทั้งสามนี้ไม่ผ่านการแสดงออกปกติของคุณอาจไม่อนุญาตให้ใช้โดเมนที่ถูกต้อง!

ดูหน้าการสนับสนุนชื่อโดเมนสากลจากคู่มือสภาพแวดล้อมภาษาสากลของ Oracleสำหรับข้อมูลเพิ่มเติม

อย่าลังเลที่จะลอง regex ที่นี่: http://www.regexr.com/3abjr

ICANNเก็บรายการ tlds ที่ได้รับมอบหมายซึ่งสามารถใช้เพื่อดูตัวอย่างโดเมน IDN


แก้ไข:

 ^(((?!-))(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,})$

นิพจน์ทั่วไปนี้จะหยุดโดเมนที่มี '-' ต่อท้ายชื่อโฮสต์ว่าถูกทำเครื่องหมายว่าถูกต้อง นอกจากนี้ยังอนุญาตให้มีโดเมนย่อยได้ไม่ จำกัด


1
โปรดทราบว่าสิ่งนี้จะรองรับโดเมนย่อยสูงสุดหนึ่งโดเมนเท่านั้นสิ่งที่มากกว่านั้นจะทำให้เป็นเท็จ ไม่ใช่สิ่งที่คุณจะถูกหมิ่นประมาทเว้นแต่จะใช้กับไซต์ภายใน ฯลฯ ... ความพยายามอย่างรวดเร็วเพื่อให้รองรับโดเมนย่อยเพิ่มเติม:/^((?!-))(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
แต่ tld ของ lonely ไม่ทำงาน :( ตัวอย่างเช่นto.( ถึง. ) เป็น URL ที่ถูกต้องพร้อมเนื้อหา
iiic

@iiic ใช่ แต่to.ไม่ใช่ชื่อโดเมนที่มีคุณสมบัติครบถ้วน หากคุณต้องการอนุญาตโดเมนระดับบนสุดคุณควรใช้สิ่งที่ต้องการ^(((?!-))(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,})\.?$แต่ขอเตือนคุณจะปล่อยให้คนที่ใส่โดเมนเช่นtestหรือnaด้วย!
Tim Groeneveld

ยอมรับinvali.dเป็นชื่อโดเมนที่ถูกต้องในขณะที่invali.d.co.ukไม่ถูกต้อง
Pawel Krakowiak

1
ควรสังเกตว่าxn--stackoverflow.comไม่ใช่ชื่อที่ถูกต้องเนื่องจากไม่สามารถแปลง 'stackoverflow' จาก Punycode ได้ อย่างไรก็ตามนั่นเกินกว่าที่ regex จะทำได้ ตามข้อสังเกตทั่วไปxn--[a-z0-9]+ป้ายกำกับจะเป็น IDN เท่านั้นในขณะที่xn--[a-z0-9]+\-[a-z0-9]+ระบุการผสมระหว่างอักขระ ASCII และไม่ใช่ ASCII
Marcus

50

RegEx ของฉันอยู่ถัดไป:

^[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})$

ใช้ได้สำหรับi.oh1.meและสำหรับwow.british-library.uk

UPD

นี่คือกฎที่อัปเดต

^(([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})$

การแสดงภาพนิพจน์ทั่วไป

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

ตอนนี้จะตรวจสอบ-หรือ_ในป้ายเริ่มต้นหรือจุดสิ้นสุดของโดเมน


9
ดูดีทีเดียว แต่{2,6}เกณฑ์จะต้องได้รับการอัปเดตสำหรับ TLD ใหม่ น่าจะ{2,}.
jwatts1980

@ jwatts1980 มีตัวอย่างโซนดังกล่าวหรือไม่? หรือคุณหมายถึงโซนในอนาคตที่เป็นไปได้?
paka

1
นี่คือบทความที่กล่าวถึงการเปลี่ยนแปลงที่จะเกิดขึ้นพร้อมตัวอย่างและลิงค์ไปยังแหล่งข้อมูลที่เกี่ยวข้อง: zdnet.com/…
jwatts1980

1
ทำไม ([a-zA-Z] {1} [a-zA-Z] {1}) และไม่เป็น ([a-zA-Z] {2})
Anton

3
ส่วนสุดท้ายที่มีทางเลือกสองทางก็ผิดเช่นกัน: มี ccTLD (ตัวอักษรสองตัว) ที่ยอมรับป้ายย่อย IDNA นอกจากนี้ยังมีป้ายกำกับ TLD ที่ใช้ป้ายกำกับ IDNA อยู่แล้ว คุณไม่ควรเป็นกรณีพิเศษที่ป้ายกำกับสุดท้ายซึ่งไม่แตกต่างจากป้ายอื่น ๆ (และตอนนี้มีส่วนขยายจำนวนมากที่เพิ่มความยาวตัวแปร jsut เหมือนกับป้ายกำกับอื่น ๆ ในโดเมนย่อยโปรดทราบว่าป้ายกำกับ IDNA อาจปรากฏเป็น Punycoded ด้วย (ในกรณีนี้จะมี "- - "ส่วนหนึ่งในป้ายกำกับกรณีเดียวที่อนุญาต" - "ในป้ายกำกับ .. สุดท้ายขีดล่างก็ไม่ถูกต้องทุกที่ในป้ายกำกับทั้งหมด
verdy_p

24

เดิมพันของฉัน:

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

อธิบาย:

ชื่อโดเมนสร้างจากเซ็กเมนต์ นี่คือหนึ่งส่วน (ยกเว้นขั้นสุดท้าย):

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

สามารถมีได้ 1-63 อักขระไม่ขึ้นต้นหรือลงท้ายด้วย "-"

ต่อท้าย "." ทำซ้ำอย่างน้อยหนึ่งครั้ง:

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

จากนั้นแนบส่วนสุดท้ายซึ่งมีความยาว 2-63 อักขระ:

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

ทดสอบได้ที่นี่: http://regexr.com/3au3g


@GaneshBabu คุณหมายถึงอะไรที่ตรงกัน?
Yaroslav Stavnichiy

1
คำตอบอื่น ๆ ทั้งหมดไม่ได้ผลสำหรับฉัน แต่คำตอบนี้ทำได้
Danny Coulombe

ฉันมีข้อกำหนดที่คล้ายกันซึ่งฉันต้องการหลีกเลี่ยงอัฒภาคและลูกน้ำในตอนท้ายฉันพยายามมาก แต่ไม่ประสบความสำเร็จด้านล่างนี้คือ Regex ที่ฉันใช้ 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; มันตรวจสอบได้ว่าฉันใช้และ; อยู่ระหว่าง แต่ล้มเหลวในตอนท้ายเพื่อ vliadate
Harry

ฉันพบหลายโดเมนที่ควรจะถูกต้อง แต่ไม่ถูกต้องกับ regex ของคุณ ตัวอย่างเช่นредбулл.москваเป็นโดเมนที่ถูกต้องหรือредбулл.рфและ红色的公牛中国
pubkey

1
@pubkey คุณต้องแปลงชื่อโดเมนเหล่านั้นเพื่อpunycode ชื่อจริงสำหรับредбулл.москваคือ xn - 90afc0aazy.xn - 80adxhks และ regex ของฉันตรงกับมัน
Yaroslav Stavnichiy

13

เพียงการแก้ไขเล็กน้อย - ส่วนสุดท้ายควรเป็น 6 ดังนั้น

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

TLD ที่ยาวที่สุดคือmuseum(6 ตัวอักษร) - http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains


3
หมายเหตุ: สิ่งนี้จะไม่ส่งผ่านชื่อโดเมนที่ถูกต้อง (แต่หายาก) www.my---domain.com
Chris Bier

17
ไม่ได้ตัดด้วย TLD ใหม่เช่น.photography
Sam Figueroa

2
@SamFigueroa คุณจะต้องปรับเปลี่ยนความยาวของมัน
Steel Brain

3
ไม่ควรมีการตรวจสอบ TLD ซึ่งไม่แตกต่างจากโดเมนย่อย และการอ้างอิง regex บนavailabletlds ในปัจจุบันไม่ใช่ข้อพิสูจน์ในอนาคต
Loïc Faure-Lacroix

1
แนะนำบิตสุดท้ายเป็น{2,63}: ดูstackoverflow.com/questions/9238640/…
Eric Dobbs

13

คำตอบที่ยอมรับไม่ได้ผลสำหรับฉันลองสิ่งนี้:

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

เยี่ยมชมกรณีทดสอบหน่วยนี้เพื่อตรวจสอบความถูกต้อง


4
ไม่รองรับชื่อ TLD ใหม่ที่ยาวขึ้นเช่น. audio, .photography และส่วนใหญ่ ... data.iana.org/TLD/tlds-alpha-by-domain.txt
mrbinky3000

@ mrbinky3000 แค่เปลี่ยนสุดท้าย{2,6}เป็นอย่างอื่นก็ใช้ได้ ของฉัน:^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+(?!-)[a-zA-Z0-9-]{1,63}(?<!-)$
Mygod

@Mygod regex ของคุณมีขยะที่มีความกว้างเป็นศูนย์อยู่เลยเครื่องหมายคำถามสุดท้ายดังนั้นใครก็ตามที่คัดลอกมันจะต้องแปลกใจอย่างไม่น่าเชื่อ
MightyPork

1
@MightyPork คุณพูดถูก! ขออภัยที่นี่เป็นเวอร์ชันที่สะอาด (หวังว่า):^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+(?!-)[a-zA-Z0-9-]{1,63}(?<!-)$
Mygod

ดีมาก. อนิจจานิพจน์ lookbehind ไม่ถูกต้องใน JavaScript : /
ฟีลโฮ

13

คำตอบนี้ใช้สำหรับชื่อโดเมน (รวมถึง RR ของบริการ) ไม่ใช่ชื่อโฮสต์ (เช่นชื่อโฮสต์อีเมล)

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

มันเป็นคำตอบของ mkyongโดยทั่วไปและนอกจากนี้:

  • ความยาวสูงสุด 255 อ็อกเต็ตรวมถึงคำนำหน้าความยาวและรูทว่าง
  • อนุญาตให้ต่อท้าย "." สำหรับรูท dns ที่ชัดเจน
  • อนุญาตให้นำ '_' สำหรับโดเมนบริการ RRs (ข้อบกพร่อง: ไม่บังคับใช้สูงสุด 15 อักขระสำหรับป้ายกำกับ _ และไม่จำเป็นต้องมีโดเมนอย่างน้อยหนึ่งโดเมนเหนือบริการ RRs)
  • ตรงกับ TLD ที่เป็นไปได้ทั้งหมด
  • ไม่จับป้ายกำกับโดเมนย่อย

โดยอะไหล่

Lookahead จำกัดความยาวสูงสุดระหว่าง ^ $ ถึง 253 อักขระโดยมีตัวอักษรต่อท้าย "."

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

Lookahead อักขระถัดไปไม่ใช่ "-" และไม่มี "_" ตามหลังอักขระใด ๆ ก่อนหน้า "ถัดไป" กล่าวคือบังคับว่าอักขระตัวแรกของป้ายกำกับไม่ใช่ "-" และอักขระตัวแรกเท่านั้นที่สามารถเป็น "_" ได้

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

ระหว่าง 1 ถึง 63 ของอักขระที่อนุญาตต่อป้ายกำกับ

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

Lookbehind อักขระก่อนหน้าไม่ใช่ "-" กล่าวคือบังคับว่าอักขระสุดท้ายของป้ายกำกับไม่ใช่ "-"

(?<!-)

บังคับ a "." ที่ส่วนท้ายของป้ายกำกับทุกป้ายยกเว้นป้ายสุดท้ายซึ่งเป็นทางเลือก

(?:\.|$)

โดยส่วนใหญ่รวมกันจากข้างบนสิ่งนี้ต้องใช้ระดับโดเมนอย่างน้อยสองระดับซึ่งไม่ถูกต้องนัก แต่โดยปกติจะเป็นข้อสันนิษฐานที่สมเหตุสมผล เปลี่ยนจาก {2,} เป็น + หากคุณต้องการอนุญาต TLDs หรือโดเมนย่อยสัมพัทธ์ที่ไม่มีเงื่อนไขผ่าน (เช่น localhost, myrouter ถึง.)

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

การทดสอบหน่วยสำหรับนิพจน์นี้


1
ขอบคุณ! นี่คือ regex ที่ดีที่สุดที่นี่ คำอธิบายอย่างละเอียดและการทดสอบหน่วยเป็นโบนัส
naudster

"RR" หมายถึงอะไร
นายท้าย

บันทึกทรัพยากร โดยปกติจะเป็นช่องข้อความหรือข้อมูลที่บอกวิธีโต้ตอบกับบริการ
Andrew Domaszek

นิพจน์ทั่วไปนี้ไม่ถูกต้อง ตัวอย่างเช่นโดเมน redbull 移动ถูกต้อง แต่ regex จะไม่ตรงกัน
pubkey

แปลงเป็น punycode ก่อนจากนั้นจับคู่ การจำกัดความยาวของเวอร์ชันก่อน punycode นั้นยากที่จะนำไปใช้
Andrew Domaszek

8

ขอบคุณสำหรับการชี้ทิศทางที่ถูกต้องในโซลูชันการตรวจสอบชื่อโดเมนในคำตอบอื่น ๆ ชื่อโดเมนสามารถตรวจสอบได้หลายวิธี

หากคุณต้องการตรวจสอบความถูกต้องของโดเมนIDNในรูปแบบที่มนุษย์อ่านได้ regex \p{L}จะช่วยได้ สิ่งนี้ช่วยให้จับคู่อักขระในภาษาใดก็ได้

โปรดทราบว่าส่วนสุดท้ายอาจมีขีดกลางด้วย! เนื่องจากชื่อภาษาจีนที่เข้ารหัส punycode อาจมีอักขระ Unicode เป็น tld

ฉันได้มาถึงวิธีแก้ปัญหาซึ่งจะตรงกับตัวอย่าง:

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

Regex คือ:

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

ตรวจสอบและปรับแต่งที่นี่

หมายเหตุ: regexp นี้ค่อนข้างอนุญาตเช่นเดียวกับชื่อโดเมนปัจจุบันที่อนุญาตให้ใช้ชุดอักขระ

อัปเดต : ง่ายยิ่งขึ้นเช่นa-aA-Z\p{L}เดียวกับเพียง\p{L}

NOTE2: ปัญหาเดียวคือจะจับคู่โดเมนที่มีจุดสองจุดในนั้น ... เช่นmasełk..owski.pl. หากใครทราบวิธีแก้ไขโปรดปรับปรุง


เราสามารถใช้[:alpha:]และ[:digit]แทน\p{L}. มันทำงานได้ดี
puchu

คุณไม่สามารถตรวจสอบ IDN ได้ด้วยวิธีนี้โดยไม่ต้องแปลงเป็น punycode ก่อน ตัวอย่างเช่นด้วย expr ของคุณ中国互联网络信息中心中国互联网络信息中心中国互联网络信.中国ตรวจสอบว่าถูกต้อง แต่หลังจากการแปลง IDN จำนวนไบต์ต่อป้ายกำกับมากเกินไป \ p {L} จับคู่สัญลักษณ์ไม่ใช่ punycode ไบต์ (ซึ่งแตกต่างกันไปในแต่ละสัญลักษณ์) ดังนั้นการนับซ้ำจึงไม่เป็นประโยชน์เมื่อพยายาม จำกัด ขนาดหลังการแปลง
Andrew Domaszek

จุดดีแต่ละส่วน จำกัด ที่ 64 ไบต์ อย่างไรก็ตามเราไม่สามารถตรวจสอบด้วย RegExp ได้ดังนั้นจึงต้องมีขั้นตอนการตรวจสอบความถูกต้องเพิ่มเติมโดยใช้ตัวถอดรหัส punycode ซึ่งจะล้มเหลวกับชื่อโฮสต์ตัวอย่างของคุณ ชาวจีนต้องคลั่งเพราะข้อ จำกัด นี้
PeterM

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

[โดเมน - อักษรตัวพิมพ์เล็กและ 0-9 เท่านั้น] [สามารถมียัติภังค์] + [TLD - ตัวพิมพ์เล็กเท่านั้นต้องอยู่ระหว่าง 2 ถึง 7 ตัวอักษร]
http://rubular.com/ยอดเยี่ยมสำหรับการทดสอบนิพจน์ทั่วไป!
แก้ไข: อัปเดต TLD สูงสุด 7 อักขระสำหรับ ".rentals" ตามที่ Dan Caddigan ชี้ให้เห็น


1
ทำไมต้อง จำกัด TLD ตอนนี้.photographyจะไม่ถูกต้อง เพียงแค่สร้างตัวอักษรไม่ จำกัด หรืออะไรทำนองนั้น
adriaan

5

ตัวแทนยังไม่เพียงพอที่จะแสดงความคิดเห็น ในการตอบสนองต่อวิธีแก้ปัญหาของ paka ฉันพบว่าฉันต้องปรับสามรายการ:

  • มีการย้ายเส้นประและขีดล่างเนื่องจากเส้นประถูกตีความเป็นช่วง (เช่น "0-9")
  • เพิ่มตัวหยุดเต็มสำหรับชื่อโดเมนที่มีโดเมนย่อยมากมาย
  • ขยายความยาวที่เป็นไปได้สำหรับ TLD เป็น 13

ก่อน:

^(([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})$

หลังจาก:

^(([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

สำหรับ gTLD ใหม่

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

2
โปรดให้รายละเอียดเพิ่มเติมว่าคำตอบของคุณดีกว่าคนอื่น ๆ หรือไม่? ตรงกับอะไรมากกว่าโปรดแก้ไขโพสต์ของคุณโดยตรงเพื่อเพิ่มข้อมูล
Sven R.

อย่างที่ฉันเขียน: gTLD ใหม่ โดเมนที่มีตัวอักษร Unicode และ Unicode TLD ด้วย
Ben Keil

1
@BenKeil: เป็นส่วนหนึ่งเกี่ยวกับอะไร: (<-!)

@jor ที่มองในแง่ลบไม่ทัน. ลองดูที่ทางลัด
foo.com/app/dojos/regex/cheatsheet

3

ดังที่ได้กล่าวไปแล้วว่าไม่ชัดเจนที่จะบอกโดเมนย่อยในแง่การปฏิบัติ (เช่น.co.ukโดเมน) เราใช้ regex นี้เพื่อตรวจสอบโดเมนที่เกิดขึ้นในไวลด์ ครอบคลุมกรณีการใช้งานจริงทั้งหมดที่ฉันรู้จัก คนใหม่ยินดีต้อนรับ ตามหลักเกณฑ์ของเราจะหลีกเลี่ยงกลุ่มที่ไม่จับภาพและการจับคู่แบบโลภ

^(?!.*?_.*?)(?!(?:[\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})$

หลักฐานคำอธิบายและตัวอย่าง: https://regex101.com/r/FLA9Bv/9 ( หมายเหตุ: ขณะนี้ใช้งานได้เฉพาะใน Chrome เนื่องจาก regex ใช้ lookbehinds ซึ่งรองรับเฉพาะใน ECMA2018 )

มีสองวิธีให้เลือกในการตรวจสอบโดเมน

การจับคู่ FQDN ตามหนังสือ (คำจำกัดความทางทฤษฎีไม่ค่อยพบในทางปฏิบัติ):

  • ยาวสูงสุด 253 อักขระ (ตามRFC-1035 / 3.1 , RFC-2181/11 )
  • ความยาวสูงสุด 63 อักขระต่อฉลาก (ตามRFC-1035 / 3.1 , RFC-2181/11 )
  • อนุญาตให้ใช้อักขระใดก็ได้ (ตามRFC-2181/11 )
  • TLD ไม่สามารถเป็นตัวเลขทั้งหมด (ตามRFC-3696/2 )
  • FQDN สามารถเขียนในรูปแบบที่สมบูรณ์ซึ่งรวมถึงโซนรูท (จุดต่อท้าย)

การจับคู่ FQDN ในทางปฏิบัติ / เชิงอนุรักษ์ (คำจำกัดความในทางปฏิบัติคาดหวังและสนับสนุนในทางปฏิบัติ):

  • by-the-books ที่ตรงกับข้อยกเว้น / ส่วนเพิ่มเติมต่อไปนี้
  • อักขระที่ถูกต้อง: [a-zA-Z0-9.-]
  • ป้ายกำกับไม่สามารถเริ่มต้นหรือลงท้ายด้วยยัติภังค์ (ตามRFC-952และRFC-1123 / 2.1 )
  • ความยาวขั้นต่ำ TLD คือ 2 อักขระความยาวสูงสุดคือ 24 อักขระตามบันทึกที่มีอยู่ในปัจจุบัน
  • ไม่ตรงกับจุดต่อท้าย

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

5
-1 สำหรับการเพิ่ม {2,4} เป็นไปได้ที่จะมี TLD อักขระเดียว (อย่างไรก็ตามขณะนี้ยังไม่มีในรูท) แล้ว. mobile ล่ะ? .associates? ทั้งสองเป็น TLD ที่ถูกต้องและ regex นี้จะปฏิเสธ data.iana.org/TLD/tlds-alpha-by-domain.txt
Tim Groeneveld

2

นี่คือรหัสที่สมบูรณ์พร้อมตัวอย่าง:

<?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})$

ขอบคุณ @mkyong สำหรับคำตอบของฉัน ฉันได้แก้ไขเพื่อรองรับป้ายกำกับที่ยาวขึ้นแล้ว

นอกจากนี้ "localhost" เป็นชื่อโดเมนที่ถูกต้องในทางเทคนิค ฉันจะแก้ไขคำตอบนี้เพื่อรองรับชื่อโดเมนสากล


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}) -> สำหรับการยอมรับเพียงสองตัวละคร

  • ([0-9]{1,2})-> สำหรับการรับสองหมายเลขเท่านั้น

หากมีสิ่งใดเกินกว่าสอง ([a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]) regex นี้จะดูแลสิ่งนั้น

หากเราต้องการทำการจับคู่อย่างน้อยหนึ่งครั้ง+จะถูกใช้


0

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

ตัวอย่างที่ใช้งานได้:

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

นอกจากนี้ยังใช้งานได้กับส่วนขยาย

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

ตัวอย่างที่ใช้ไม่ได้:

-stack.com

มันจะทำงานได้แม้จะมีนามสกุลโดเมนที่ยาวที่สุด ".versicherung"



0

regex ต่อไปนี้จะแยกย่อย root และ tld ของโดเมนที่กำหนด:

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

ผ่านการทดสอบสำหรับโดเมนต่อไปนี้:

* 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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.