Подтвердить что ты не робот

Regexp для поддомена

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

Я попробовал следующее:

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

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

4b9b3361

Ответ 1

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-адрес) должен отвечать дополнительным требованиям:

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

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

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

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

Ответ 2

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

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

Ответ 3

В нашем проекте мы сопоставляем субдомены, подобные этому

Клиент 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

Ответ 4

Попробуйте следующее:

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

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

Ответ 5

Вот решение 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",
     "@[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;
        });
    });
});

Другие тесты очень приветствуются!

Ответ 6

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

Ответ 7

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

^(?![-.])[a-zA-Z0-9.-]+(?<![-.])$

Ответ 8

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

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

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

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

  • abc.com
  • abc_xyz.com
  • abc.xyz.com
  • азбука

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

  • а.
  • -abc
  • abc-
  • хуг. abc-
  • https://abcxyz.com