EZW Ответов: 3

Регулярное выражение для проверки URL-адреса


Мне нужно регулярное выражение, которое проверяло бы следующие формы URL-адреса

http://www.site.com
https://www.site.com
http://site.com
https://site.com
http://domain.site.com
https://domain.site.com
http://www.domain.site.com
https://www.domain.site.com
site.com 
domain.site.com
http://www.site.com/path/to/dir/
https://www.site.com/path/to/dir/
http://site.com/path/to/dir/
https://site.com/path/to/dir/
http://domain.site.com/path/to/dir/
https://domain.site.com/path/to/dir/
http://www.domain.site.com/path/to/dir/
https://www.domain.domain.site.com/path/to/dir/
site.com/path/to/dir/
domain.site.com/path/to/dir/
http://www.site.com/path/to/file.html
https://www.site.com/path/to/file.html
http://site.com/path/to/file.html
https://site.com/path/to/file.html
http://domain.site.com/path/to/file.html
https://domain.site.com/path/to/file.html
http://www.domain.site.com/path/to/file.html
https://www.domain.domain.site.com/path/to/file.html
site.com/path/to/file.html
domain.site.com/path/to/file.html

И относительные пути
./path/to/file.html
./path/to/dir/
./path/to/dir
path/to/file.html
path/to/dir/
path/to/dir

(ftp:// не разрешен)

Расширение файла может быть html, php, gif, jpg, png.

С моим знанием регулярных выражений это заняло бы у меня год (если не больше). Вчера мне потребовалось больше часа, чтобы сделать регулярное выражение для относительного URL, и это оказалось не так, как я хочу! Я чувствую, что должен извиниться за то, что не знаю регулярных выражений! :(

Просто хочу отметить, что это не проблема, если URL-адрес действительно никуда не указывает, моя главная забота-это формат. Мне просто нужно, чтобы формат был в тех (и только в тех), как показывают примеры (это исчерпывающий список). Только это то, что я буду использовать и нуждаться, но если он проверяет другой формат, то это нормально (до тех пор, пока его только http / https... ftp, ftps или что-то еще не разрешено).

Maarten Kools

RegExr[^] имеет библиотеку сообщества, которая также содержит множество выражений проверки URL-адресов, которые должны дать вам быстрый старт. Оттуда вам придется немного подправить выражения, чтобы получить желаемый результат.

EZW

лол, это на самом деле то, что я сейчас делаю и пытаюсь сделать, пока жду предложений (хотя большое спасибо за ваш комментарий). Я либо нарушаю его, либо вообще не получаю никаких новых результатов.

Vedat Ozan Oner

спасибо за ссылку. это здорово :)

Maarten Kools

Всегда пожалуйста, буду рад помочь :)

Vedat Ozan Oner

((http|https)://)?[a-zA-Z]\w*(\.\w+)+(/\w*(\.\w+)*)*(\?.+)* это хорошо для URL :)

EZW

Это правильно проверяет все мои абсолютные URL-адреса, но не мои относительные URL-адреса. :) может быть, я могу немного изменить его. Я попробую изменить его... мои знания в регулярном выражении довольно плохи. Большое спасибо за этот пост... он там на 90%... это делает меня намного ближе :D

Andreas Gieriet

Что именно Вы имеете в виду под "проверкой"? Вы хотите проверить, являются ли URL-адреса формально правильными, то есть в соответствии с соответствующими RFC 1738 и википедия: URL?
Какие из перечисленных Вами URL-адресов считаются правильными, на ваш взгляд? http://machine.domain.gaga/ формально корректен, но имеет бессмысленную часть имени хоста (gaga).
Вы также можете столкнуться с # и & и % и ? и = и ; в задней части это может иметь прекрасный смысл. Каково ваше ожидание от "проверки" на них (см. RFC выше еще раз). Пожалуйста, обратите внимание, что только полный URL-адрес является правильным URL-адресом, если схема отсутствует, вы можете угадать схему, но это чистая эвристика. Возможно, вам нужно улучшить свой вопрос (и решить, чего вы действительно хотите достичь), чтобы любой здесь мог дать вам удовлетворительный ответ. Я думаю, что требования сформулированы недостаточно хорошо. Это может быть причиной, по которой вы не достигаете, чтобы получить рабочее решение.
Кстати: я думаю, вы не можете легко решить его с помощью *одного* регулярного выражения. Вероятно, вам нужно разбить текст на различные части и проверить их по отдельности (не обязательно с помощью регулярных выражений).
Овации
Энди

EZW

Привет, большое спасибо за этот конструктивный ответ. URL-адреса будут сгенерированы системой, поэтому они будут действительны при нормальных обстоятельствах, но эти сгенерированные URL-адреса будут находиться в таком месте, где они могут быть изменены пользователем (например, в URL-запросе), поэтому мне нужно проверить его, если он находится в правильном формате, чтобы я не оставлял систему открытой для атак. Ведут ли URL-адреса куда-то, мне все равно... если они никуда не ведут, у меня есть запасной вариант (или если он не открывается, выполните действие по умолчанию). Мне просто нужно регулярное выражение, которое проверяет (или подтверждает), что URL-адрес находится в приемлемом формате (как примеры (которые являются исчерпывающими), показанные в исходном сообщении).

3 Ответов

Рейтинг:
22

Peter Leow

Попробовать это:

(^(http[s]?://)?([w]{3}[.])?([a-z0-9]+[.])+com(((/[a-z0-9]+)*(/[a-z0-9]+/))*([a-z0-9]+[.](html|php|gif|png))?)$)|(^([.]/)?((([a-z0-9]+)/?)+|(([a-z0-9]+)/)+([a-z0-9]+[.](html|php|gif|png)))?$)


EZW

С небольшой модификацией я заставил его работать!!! Большое вам спасибо, сэр!!!!!!!

((^(http[s]?:\/\/)?([w]{3}[.])?(([a-z0-9\.]+)+(com|php))(((\/[a-z0-9]+)*(\/[a-z0-9]+\/?))*([a-z0-9]+[.](html|php|gif|png|jpg))?)$)|((^([.]\/)?((([а-З0-9]+)\/?)+|(([а-З0-9]+)\/)+([а-З0-9]+[.](на html|php в|гиф|ПНГ|формате JPG))))$))

Peter Leow

Я вижу, что вы добавили в расширение jpg и escape для php. Я проверил,это работает для site.com -тоже. Принять это как ответ?

EZW

Он действительно работает для всего :D я поверил онлайн-тестеру регулярных выражений, который показал другие результаты, чем мой Apache... теперь я знаю, что им нельзя доверять, лол принял! Большое спасибо

Рейтинг:
2

farazpo

Вы можете попробовать это просто:

Uri.IsWellFormedUriString(YourURLString, UriKind.RelativeOrAbsolute)


Видеть MSDN


CHill60

За исключением того, что URI и URL - это не одно и то же-последнее является только подмножеством первого

Рейтинг:
13

Andreas Gieriet

Вы можете попробовать это (немного короче, чем Решение №1):

^((https?:[/][/])?\w+[.])+com|((https?:[/][/])?\w+[.])+com[/]|[.][/])?\w+([/]\w+)*([/]|[.]html|[.]php|[.]gif|[.]jpg|[.]png)?)$

[EDIT1]
Правильная картина была
^((https?:[/][/])?(\w+[.])+com|((https?:[/][/])?(\w+[.])+com[/]|[.][/])?\w+([/]\w+)*([/]|[.]html|[.]php|[.]gif|[.]jpg|[.]png)?)$
В скобках была допущена ошибка.
[/EDIT1]

Это разлагается на (The <yyy> need to be replaced by the respective patterns):
<valid>        = <prefix>|(<prefix>[/]|[.][/])?<path>
<prefix>       = (https?:[/][/])?<host>
<host>         = \w+([.]\w+)*[.]com
<path>         = \w+([/]\w+)*([/]|[.]html|[.]php|[.]gif|[.]jpg|[.]png)?

[EDIT2]
Запрос идет после пути или, если путь отсутствует, после префикса - ни один запрос не допускается для parh без префикса.
[/EDIT2]

[EDIT3]
Чтобы управлять сложностью, разбейте шаблоны на отдельные переменные и объедините их с полным шаблоном. Это позволяет протестировать части полного шаблона.

Напр.
// query
$rx_qpart = '\\w+=[^&]*';
$rx_qhead = '[?]'.$rx_qpart;
$rx_qnext = '[&]'.$rx_qpart;
$rx_qtail = '('.$rx_qnext.')*';
$rx_query = '('.$rx_qhead.$rx_qtail.')?'; // *** to be used in the main pattern
// path
$rx_ppart = '\\w+';
$rx_phead = $rx_ppart;
$rx_pnext = '[/]'.$rx_ppart;
$rx_ptail = '('.$rx_pnext.')*';
$rx_pdend = '[/]';
$rx_pfend = '[.]html|[.]php|[.]gif|[.]jpg|[.]png';
$rx_pend  = '('.$rx_pdend.'|'.$rx_pfend.')?':
$rx_rpath = $rx_phead.$rx_ptail.$rx_pend;                     // *** to be used in the main pattern
$rx_qpath = $rx_phead.$rx_ptail.'('.$rx_pfend.')?'.$rx_query; // *** to be used in the main pattern
// host
$rx_hpart = '\\w+';
$rx_hhead = $rx_hpart;
$rx_hnext = '[.]'.$rx_hpart;
$rx_htail = '('.$rx_hnext.')*';
$rx_top   = '[.]com'; // I suggest to replace by $rx_top = $rx_hnext;
$rx_host  = $rx_hhead.$rx_htail.$rx_top; // *** to be used in the main pattern
// protocol
$rx_protocol = '(https?:[/][/])?'; // *** to be used in the main pattern
// prefix
$rx_prefix = $rx_protocol.$rx_host;
// **** full pattern ****
$rx_url = '^('.$rx_prefix.'[/]?';
          .'|'.$rx_prefix.'[/]'.$rx_qpath
          .'|'.$rx_prefix.$rx_query
          .'|'.$rx_rpath
          .'|'.'[.][/]'.$rx_rpath
          .')$';
Примечание: вы должны использовать одинарные кавычки, чтобы избежать дальнейшей интерпретации PHP-интерпретатором вложенных специальных символов, таких как &, прием.
[/EDIT3]


Овации
Энди


EZW

Это меньше, но я получаю неизвестный модификатор '?' error... если я поставлю '/' на любом конце, ошибка изменится на неизвестный модификатор ']'. Спасибо за помощь :D

EZW

Теперь это работает... хотя и немного изменено, так как скобки были неправильно подобраны

(^((https?:[/][/])?\w+[.])+com|(((https?:[/][/])?\w+[.])+com[/]|[.][/])?\w+([/]\w+)*([/]|[.]html|[.]php|[.]gif|[.]jpg|[.]png)?)$

Теперь у меня есть еще одна проблема (тогда я этого не предвидел :/ ) мне нужно регулярное выражение, чтобы разрешить строку запроса.

Andreas Gieriet

Есть список примеров?
Добавление строки запроса должно быть сделано в префиксе, после хоста. например. <query> = ([?]\w+=\w*(&\w+=\w*)*)?
Смотрите мое обновленное решение выше.
Овации
Энди
PS: я исправил свой шаблон. У него действительно была проблема с круглыми скобками.

EZW

Я получаю:

Предупреждение: preg_match(): неизвестный модификатор ']'

:(

Andreas Gieriet

Как-то я упустил из виду, что вы хотите его для PHP. Я действительно удивлялся, почему это сработало для меня, но не для тебя. Мое решение предназначено для .Net (например, C#), а не для PHP. Я предполагаю, что это похоже, но может отличаться в деталях.
Овации
Энди

EZW

Ах, что может быть. Спасибо, что помогли мне, хотя я действительно ценю ваши усилия

EZW

Я исправил ошибку... есть следующее регулярное выражение, которое почти работает... все еще не допускает строк запроса (это были неэкранированные '\'и знаки (например,'? ' и '&' и '.').).

^((по протоколу HTTPS?[\:][\/][\/])?(\ж+[\.])+ком(((\&амп;|\?)\ж+\=\Вт*)*)?|((протокол HTTPS?[\:][\/][\/])?(\w+[\.])+com(((\&|\?)\w+\=\w*)*)?[\/]|[\.][\/])?\w+([\/]\w+)*([\/]|[\.]html|[\.]php|[\.]gif|[\.]jpg|[\.]png)?)$

EZW

Я получил следующее (от 1-го решения до работы)

((^(http[s]?:\/\/)?([w]{3}[.])?(([a-z0-9\.]+)+(com|php))(((\/[a-z0-9]+)*(\/[a-z0-9]+\/?))*([a-z0-9]+[.](html|php|gif|png|jpg))?)(((\&|\?)\w+\=\w*)*)$)|((^([.]\/)?((([а-З0-9]+)\/?)+|(([а-З0-9]+)\/)+([а-З0-9]+[.](на html|php в|гиф|ПНГ|формате JPG))))$))

Но он довольно большой, и я не знаю, правильно ли я его понял