Регулярное выражение для поддоменов - PullRequest
25 голосов
/ 28 октября 2011

Кто-нибудь знает, как написать регулярное выражение, которое позволяет только a-zA-Z0-9 .- (буквы, цифры, точки и тире) НО , которое никогда не запускается заканчивается точкой или тире?

Я попробовал это:

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

... но если я напишу что-то вроде "john @", это сработает, и я не хочу, потому что @ не разрешено.

Ответы [ 8 ]

73 голосов
/ 28 октября 2011

Субдомен

Согласно соответствующим интернет-рекомендациям ( 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)адрес), должны соответствовать дополнительным требованиям:

  • Имя хоста может состоять из нескольких частей поддоменов, каждая из которых разделена одной точкой.
  • Длина полного имени хоста не должна превышать 255 символов.
  • Домен верхнего уровня (самая правая часть имени хоста DNS) должен быть одним из международно признанных значений.Список действительных доменов верхнего уровня поддерживается IANA.ORG.(См. Текущий список «голых костей» здесь: http://data.iana.org/TLD/tlds-alpha-by-domain.txt).

Имея это в виду, здесь приведено регулярное выражение с комментариями (в синтаксисе PHP), которое будет псевдо-проверять имя хоста DNS: (Обратите внимание, чтоэто включает в себя измененную версию вышеприведенного выражения для субдомена и также добавляет комментарии к этому.)

Обновление 2016-08-20: Поскольку этот ответ был первоначально опубликован еще в 2011 году,количество доменов верхнего уровня взорвалось. По состоянию на август 2016 года их стало более 1400. Первоначальное регулярное выражение для этого ответа включало в себя все это, но это не практично. Новое регулярное выражение ниже включает другое выражение для верхнего уровня.домен уровня. Алгоритм имеет вид: Спецификация доменного имени верхнего уровня 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, не имеющего поддомен (но это редко).

Обновление 2014-08-12: Добавлен упрощенный expression для субдомена, который не требует чередования.

Обновление 2016-08-20: Изменено регулярное выражение имени хоста DNS, чтобы оно (в более общем смысле) соответствовало новому большому числу допустимых доменов верхнего уровня.Также обрезан ненужный материал из ответа.

9 голосов
/ 28 октября 2011

Вы хотите, чтобы первый и последний символы были ограничены буквенно-цифровыми.То, что у вас теперь есть, позволяет первым и последним символам быть чем угодно, кроме точки и тире.Это соответствует описанию:

/^[a-zA-Z0-9][a-zA-Z0-9.-]+[a-zA-Z0-9]$/
2 голосов
/ 21 сентября 2017

В нашем проекте мы сопоставляем подобласти подобного типа

Клиент 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,})$

Сервер Ruby

\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
1 голос
/ 06 марта 2018

Вот DOMAIN + 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",
     "@jefe@dd.ru@22-",
     "example.net?1222",
     "example.com:8080:",
     ".example.com:8080:",
     "---test.com",
     "$dollars$.gb",
     "sell-.me",
     "open22.the-door@koll.ru",
     "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 голос
/ 28 октября 2011

Попробуйте это:

/^[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.-]*$/

Но вы должны сделать дополнительную проверку, чтобы убедиться, что конец строки не является ни точкой, ни чертой.

0 голосов
/ 01 февраля 2019

Вот регулярное выражение для субдомена, который

  • Разрешить точку (.), Подчеркивание (_), тире (-) в строке
  • Не разрешить точку (.),подчеркивание (_), тире (-) в первом и последнем символе
  • Разрешить буквенно-цифровые символы в строке

    ^[a-zA-Z0-9]+[a-zA-Z0-9-._]*[a-zA-Z0-9]+$

Правильный пример

  • abc.com
  • abc_xyz.com
  • abc.xyz.com
  • abc

Неверный пример

0 голосов
/ 28 октября 2011

Попробуйте это regex:

^(?![-.])[a-zA-Z0-9.-]+(?<![-.])$
0 голосов
/ 28 октября 2011

Попробуйте это reg-exp /^[a-zA-Z0-9][a-zA-Z0-9.-]*[a-zA-Z0-9]$/ Проблема с вашим кодом была [^.-] в начале и в конце совпадений любого символа, кроме «.» или '-', который соответствует всем символам и не обязательно [a-zA-Z0-9]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...