Regexp для субдомен

Хто-небудзь ведае, як напісаць рэгулярны выраз, што дазваляе толькі <ет> A-Za-Z0-9 .- (літары, лічбы, кропкі і працяжнік) <моцны> АЛЕ , які ніколі не пачынаецца або заканчваецца з кропкай або працяжнік?

Я паспрабаваў гэта:

/^[^.-][a-zA-Z0-9.-]+[^.-]$/

... але калі я нешта накшталт пішу «джон @», яна працуе, і я не хачу, таму што @ не дапускаюцца.

20
Што рэгулярны выраз густ? (Perl, задаць пашыранае, AWK, Вім, JavaScript ...)
дададзена аўтар Benoit, крыніца

7 адказы

Subdomain

Згодна з адпаведным рэкамендацыям Інтэрнэт ( RFC3986 раздзел 2.2 , якія, у сваю чаргу, спасылаецца у: раздзеле RFC1034 3.5 і RFC1123 раздзел 2.1 ), поддомен (які з'яўляецца часткай даменнага імя хаста DNS), павінен адказваць некалькім патрабаванням:

    <Літый> Кожны субдомен частка павінна мець даўжыню не больш, чым 63. <Літый> Кожны субдомен частка павінна пачынацца і заканчвацца літарна-лічбавы (г.зн. літарамі [A-Za-Z] або лічбаў [0-9] ).
  • Кожны поддомен частка можа ўтрымліваць злучок (працяжнік), але не могуць пачынацца ці скончвацца злучком.

Вось фрагмент выразы для подобластей часткі, якая адказвае наступным патрабаванням:

[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?

Звярніце ўвагу, што гэты фрагмент выразы не павінны выкарыстоўвацца ў адзіночку - гэта патрабуе ўключэння межавых умоў у больш шырокім кантэксце, як паказана ў наступным выразе для імя хаста DNS ...

Імя хаста DNS

Найменныя хост (не IP-адрас), павінны адказваць дадатковым патрабаванням:

  • The host name may consist of multiple Subdomain parts, each separated by a single dot.
  • The length of the overall host name should not exceed 255 characters.
  • The top level domain, (the rightmost part of the Імя хаста DNS), must be one of the internationally recognized values. The list of valid top level domains is maintained by IANA.ORG. (See the bare-bones current list here: http://data.iana.org/TLD/tlds-alpha-by-domain.txt).

With this is mind, here a commented regex (in PHP syntax), which will pseudo-validate a Імя хаста DNS: (Note that this incorporates a modified version of the above expression for a Subdomain and adds comments to this as well).

Update 2016-08-20: Since this answer was originally posted back in 2011, the number of top-level domains has exploded. As of August 2016 there are now more than 1400. The original regex to this answer incorporated all of these but this is no loger practical. The new regex below incorporates a different expression for the top-level domain. The algorithm comes from: Top Level Domain Name Specification draft-liman-tld-names-06.

$DNS_named_host = '%(?#!php/i DNS_named_host Rev:20160820_0800)
    # Match DNS named host domain having one or more Subdomains.
    # See: http://stackoverflow.com/a/7933253/433790
    ^                     # Anchor to start of string.
    (?!.{256})            # Whole domain must be 255 or less.
    (?:                   # One or more sub-domains.
      [a-z0-9]            # Subdomain begins with alpha-num.
      (?:                 # Optionally more than one char.
        [a-z0-9-]{0,61}   # Middle part may have dashes.
        [a-z0-9]          # Starts and ends with alpha-num.
      )?                  # Subdomain length from 1 to 63.
      \.                  # Required dot separates Subdomains.
    )+                    # End one or more sub-domains.
    (?:                   # Top level domain (length from 1 to 63).
      [a-z]{1,63}         # Either traditional-tld-label = 1*63(ALPHA).
    | xn--[a-z0-9]{1,59}  # Or an idn-label = Restricted-A-Label.
    )                     # End top level domain.
    $                     # Anchor to end of string.
    %xi'; //End $DNS_named_host.

Звярніце ўвагу, што гэты выраз не з'яўляецца дасканалым. Яна патрабуе аднаго або некалькі субдоменов, але тэхнічна, хост можа складацца з TLD, які не мае субдомен (але гэта рэдка).

Update 2014-08-12: Added simplified expression for Subdomain which does not require alternation.

Update 2016-08-20: Modified Імя хаста DNS regex to (more generally) match the new vast number of valid top level domains. Also, trimmed out unnecessary material from answer.

64
дададзена
@algorhythm - Мая інтэрпрэтацыя РЛК, што двайны злучок цалкам дапушчальна, але кожны поддомен частка не можа пачынацца ці скончвацца злучком.
дададзена аўтар ridgerunner, крыніца
@Qqwy - Так, вы абсалютна правы. Калі я атрымліваю нейкі час я буду абнаўляць адказ, каб адлюстраваць гэта. Дзякуй за каментар!
дададзена аўтар ridgerunner, крыніца
Нарэшце знайшоў час, каб выправіць гэтую няшмат.
дададзена аўтар ridgerunner, крыніца
ён павінен быць прыняты адказ. Ёсць што-небудзь, што я не бачыў ???
дададзена аўтар Yusuf Uzun, крыніца
Гэта добрая грубая праверка, але 1. падкрэслення цалкам законна , ^ \ ш (?: [\ W- ] {0,61} \ ш)? $ субдомен часткі працуе вельмі добра, на самай справе SRV запісаў патрабуецца іх , каб пазбегнуць сутыкненняў з нармальнымі паддаменаў 2. FYI падвойныя злучок патрабуецца для Punycode працаваць. Вядома, Вы можаце абмежаваць гэтыя запэўніванні пэўных тыпаў запісаў, але вы павінны будзеце напісаць невялікі парсер для гэтага ці нешта, што таксама дазволіць вам праверыць супраць бягучага спісу TLD :)
дададзена аўтар sg3s, крыніца
Хм, я думаю, што падвойнае «-» таксама не дзейнічае, але магчыма з гэтым рэгулярным выразам, дакладна?
дададзена аўтар algorhythm, крыніца
Звярніце ўвагу, што Anno 2016 года, ёсць яшчэ шмат дазволена двой, чым пры ўмове, DNS імя хаста рэгулярнага выраз дазваляе.
дададзена аўтар Qqwy, крыніца
Дзякуй за гэты адказ
дададзена аўтар swietyy, крыніца
дзякуй, выдатны адказ!
дададзена аўтар Pedro Emilio Borrego Rached, крыніца

Вы хочаце, каб першыя і апошнія сімвалы абмяжоўваюцца літарна-лічбавы. Тое, што вы зараз дазваляе першыя і апошнія сімвалы, каб быць нічым іншым, акрамя кропкі і працяжнік. Гэта адпавядае апісанню:

/^[a-zA-Z0-9][a-zA-Z0-9.-]+[a-zA-Z0-9]$/
8
дададзена
у test.subdomain..com ён трывае няўдачу
дададзена аўтар Dinesh Patra, крыніца
Магчыма, падкрэсліванне (_) павінна быць дазволена таксама. І невялікае заўвага: гэта рэгулярны выраз можа быць спрошчана да /^ \ ш [\ ш .-] + \ ш $/г
дададзена аўтар RReverser, крыніца
Для PHP. Дзякуй за вашу дапамогу, гэта адзін працуе выдатна: [A-Za-Z0-9] [. A-Za-Z0-9 \ - \] + [A-Za-Z0-9]
дададзена аўтар user1018527, крыніца

У нашым праекце мы супастаўляны поддомены, як гэта

кліент JS

^([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])?){2,})$

сервер лал

\A([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])?){2,})\z
2
дададзена

Тут <моцны> даменныя + SUBDOMAIN рашэнне, якое можа дапамагчы камусьці іншаму:

   /^([a-zA-Z0-9]([-a-zA-Z0-9]{0,61}[a-zA-Z0-9])?\.)?([a-zA-Z0-9]{1,2}([-a-zA-Z0-9]{0,252}[a-zA-Z0-9])?)\.([a-zA-Z]{2,63})$/

які праходзіць наступны Chai выпрабаванні:

const expect = require('chai').expect;

function testDomainValidNamesRegExp(val) {
    let names = /^([a-zA-Z0-9]([-a-zA-Z0-9]{0,61}[a-zA-Z0-9])?\.)?([a-zA-Z0-9]([-a-zA-Z0-9]{0,252}[a-zA-Z0-9])?)\.([a-zA-Z]{2,63})$/;
    return names.test(val);
} 

let validDomainNames = [
    "example.com",
    "try.direct",
    "my-example.com",
    "subdomain.example.com",
    "example.com",
    "example23.com",
    "regexp-1222.org",
    "read-book.net",
    "org.host.org",
    "org.host.org",
    "velmart.shop-products.md",
    "ip2email.terronosp-222.lb",
    "stack.com",
    "sta-ck.com",
    "sta---ck.com",
    "9sta--ck.com",
    "sta--ck9.com",
    "stack99.com",
    "99stack.com",
    "sta99ck.com",
    "sub.do.com",
    "ss.sss-ss.ss",
    "s.sss-ss.ss",
    "s.s-s.ss",
    "test.t.te"
    ];

let invalidDomainNames = [
     "example2.com222",
     "@example.ru:?",
     "example22:89",
     "@[email protected]@22-",
     "example.net?1222",
     "example.com:8080:",
     ".example.com:8080:",
     "---test.com",
     "$dollars$.gb",
     "sell-.me",
     "[email protected]",
     "mem-.wer().or%:222",
     "pop().addjocker.lon",
     "regular-l=.heroes?",
     " ecmas cript-8.org ",
     "example.com::%",
     "example:8080",
     "example",
     "examaple.com:*",
    "-test.test.com",
    "-test.com",
    "dd-.test.com",
    "dfgdfg.dfgdf33.e",
    "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd-.test.com",
    "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd.testttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt.com",
    "d-.test.com"
];

describe("Test Domain Valid Names RegExp",() => {
    validDomainNames.forEach((val) => {
        it(`Text: ${val}`,() => {
            expect(testDomainValidNamesRegExp(val)).to.be.true;
        });
    });
});

describe("Test Domain Invalid Names RegExp",() => {
    invalidDomainNames.forEach((val) => {
        it(`Text: ${val}`,() => {
            expect(testDomainValidNamesRegExp(val)).to.be.false;
        });
    });
});

Іншыя тэсты вельмі вітаюцца!

1
дададзена
абноўлены з невялікім выпраўленнем і яшчэ адзін тэст
дададзена аўтар Vasili Pascal, крыніца

Паспрабуйце гэта:

/^[a-zA-Z0-9][a-zA-Z0-9.-]*[a-zA-Z0-9]$/

АЛЕ радок павінна быць доўгімі, каб адпавядаць па меншай меры, 2 персанажа: A-Za-Z0-9 і A-Za-Z0-9. Каб пазбегнуць гэтага, вы можаце выкарыстоўваць гэта рэгулярны выраз:

/^[a-zA-Z0-9][a-zA-Z0-9.-]*$/

Але вы павінны зрабіць дадатковую праверку, каб пераканацца, што канец радка не з'яўляецца ні кропка, ні чорта.

1
дададзена

Паспрабуйце рэгулярны выраз :

^(?![-.])[a-zA-Z0-9.-]+(?
0
дададзена

Паспрабуйце рэг-EXP /^ [A-Za-Z0-9] [A-Za-Z0-9 .-] * [A-Za-Z0-9] $/ Праблема з кодам была [^ .-] у пачатковым і канчатковых матчы незалежна ад характару excpet «» ці '-', што адпавядае ўсім сімвалаў і не абавязкова [A-Za-Z0-9]

0
дададзена