Нужно регулярное выражение для проверки URL и поддержки% 20 и () - PullRequest
3 голосов
/ 15 января 2010

В настоящее время я использую следующее регулярное выражение для проверки URL:

^(?#Protocol)(?:(?:ht|f)tp(?:s?)\:\/\/|~\/|\/)?(?#Username:Password)(?:\w+:\w+@)?  (?#Subdomains)(?:(?:[-\w]+\.)+(?#TopLevel Domains)(?:com|org|net|gov|mil|biz|edu|info|mobi|name|aero|jobs|museum|travel|[a-z]{2}))(?#Port)(?::[\d]{1,5})?(?#Directories)(?:(?:(?:\/(?:[-\w~!$+|.,=]|%[a-f\d]{2})+)+|\/)+|\?|#)?(?#Query)(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)(?:&(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?#Anchor)(?:#(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)?$

Я позаимствовал это где-то в сети (не помню, где), чтобы улучшить это:

^((https?|file|ftp|gopher|news|nntp):\/\/)([a-z]([a-z0-9\-]*\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel)|(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&]*)?)?(#[a-z][a-z0-9_]*)?$

Однако, ни один из них не способен проверить этот URL (который должен быть действительным):

http://somedomain.com/users/1234/images/Staff%20Photos%202008/FirstName%20LastName_1%20(Small).jpg

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

http://www.test..com

Помощь будет оценена.

1 Ответ

4 голосов
/ 18 января 2010

Вы проверяете две вещи одним и тем же регулярным выражением:

  • Хорошо сформирован - это синтаксически правильно?
  • Правдоподобно - правдоподобно ли протокол и домен верхнего уровня?

Разделение этих проверок может быть плодотворным. Вы можете использовать это регулярное выражение, чтобы убедиться, что URI правильно сформирован. Это из RFC 3986, унифицированные идентификаторы ресурса (URI): общий синтаксис , приложение B (стр. 50):

^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?

Если URI соответствует этому регулярному выражению, оно правильно сформировано. Группы матчей дают вам различные части, которые:

scheme    = $2
authority = $4
path      = $5
query     = $7
fragment  = $9

Давайте посмотрим, что получится из приведенного вами примера URI:

2 (scheme)   : "http"
4 (authority): "somedomain.com"
5 (path)     : "/users/1234/images/Staff%20Photos%202008/FirstName%20LastName_1%20(Small).jpg"
7 (query)    : nil
9 (fragment) : nil

Теперь, когда у вас есть отдельные части, вы можете проверить каждую из них на достоверность. Например, чтобы получить TLD от органа, примените к органу следующее регулярное выражение:

\.([^.])$

Группа 1 предоставляет вам ДВУ (com, org и т. Д.), Которые вы затем можете проверить в своем списке.

...