Отримання частин URL-адреси (Regex)


132

Дана URL-адреса (один рядок):
http://test.example.com/dir/subdir/file.html

Як я можу витягнути такі частини за допомогою регулярних виразів:

  1. Субдомен (тест)
  2. Домен (example.com)
  3. Шлях без файлу (/ dir / subdir /)
  4. Файл (file.html)
  5. Шлях із файлом (/dir/subdir/file.html)
  6. URL-адреса без шляху ( http://test.example.com )
  7. (додайте будь-який інший, який, на вашу думку, буде корисним)

Регекс повинен працювати правильно, навіть якщо я ввожу таку URL-адресу:

http://example.example.com/example/example/example.html

Це не пряма відповідь, але більшість веб-бібліотек мають функцію, яка виконує це завдання. Функцію часто називають чимось схожим на CrackUrl. Якщо така функція існує, використовуйте її, вона майже гарантовано є надійнішою та ефективнішою, ніж будь-який створений вручну код.
Конрад Рудольф

7
Поясніть, будь ласка, чому це потрібно робити за допомогою регулярного вираження. Якщо це домашнє завдання, то скажіть це, тому що це ваше обмеження. В іншому випадку є кращі специфічні для мови рішення, ніж використання регулярного вираження.
Енді Лестер

1
Посилання на перший та останній зразки порушені.
Олов'яний чоловік

Тут ви можете дізнатися, як витягти схему, домен, TLD, порт та шлях запиту: stackoverflow.com/questions/9760588/…
Paolo Rovelli

Відповіді:


151

Один регулярний вираз для розбору та розбиття повної URL-адреси, включаючи параметри запиту та прив’язки, наприклад

https://www.google.com/dir/1/2/search.html?arg=0-a&arg1=1-b&arg3-c#hash

^((http[s]?|ftp):\/)?\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+[^#?\s]+)(.*)?(#[\w\-]+)?$

Позиції RexEx:

URL: RegExp ['$ &'],

протокол: рег. $ 2,

хост: рег. $ 3,

шлях: рег. $ 4,

файл: рег. $ 6,

запит: рег. $ 7,

хеш: Рег

Ви можете потім досить просто проаналізувати хост ('.' Розмежоване) досить легко.

Що я б робив, це використовувати щось подібне:

/*
    ^(.*:)//([A-Za-z0-9\-\.]+)(:[0-9]+)?(.*)$
*/
proto $1
host $2
port $3
the-rest $4

подальший розбір «решти», щоб бути максимально конкретним. Зробити це за один регулярний вираз - це трохи безумно.


4
Посилання codenippets.joyent.com/posts/show/523 не працює станом на 20 жовтня '10
W3Max

19
Проблема полягає в цій частині: (.*)?Оскільки зірка Клейна вже приймає 0 або більше, ?частина (0 або 1) плутає її. Я виправив це, змінивши (.*)?на (.+)?. Ви також можете просто видалити?
rossipedia

3
Привіт Две, я вдосконалив її трохи більше, щоб витягти example.com з таких URL-адрес, як http://www.example.com:8080/....ось: Іде:^((http[s]?|ftp):\/\/)?\/?([^\/\.]+\.)*?([^\/\.]+\.[^:\/\s\.]{2,3}(\.[^:\/\s\.]{2,3})?(:\d+)?)($|\/)([^#?\s]+)?(.*?)?(#[\w\-]+)?$
mnacos

4
і доказ того, що жоден регулярний вираз не є ідеальним, ось один негайний виправлення:^((http[s]?|ftp):\/\/)?\/?([^\/\.]+\.)*?([^\/\.]+\.[^:\/\s\.]{2,3}(\.[^:\/\s\.]{2,3})?)(:\d+)?($|\/)([^#?\s]+)?(.*?)?(#[\w\-]+)?$
mnacos

2
Я змінив цей регулярний вираз, щоб визначити всі частини URL-адреси (вдосконалена версія) - код на Python. ^((?P<scheme>[^:/?#]+):(?=//))?(//)?(((?P<login>[^:]+)(?::(?P<password>[^@]+)?)?@)?(?P<host>[^@/?#:]*)(?::(?P<port>\d+)?)?)?(?P<path>[^?#]*)(\?(?P<query>[^#]*))?(#(?P<fragment>.*))? code Ви показуєте цей код у дії на pythex.org
arannasousa

81

Я усвідомлюю, що запізнююся на вечірку, але є простий спосіб дозволити браузеру розбирати URL для вас без регулярного вираження:

var a = document.createElement('a');
a.href = 'http://www.example.com:123/foo/bar.html?fox=trot#foo';

['href','protocol','host','hostname','port','pathname','search','hash'].forEach(function(k) {
    console.log(k+':', a[k]);
});

/*//Output:
href: http://www.example.com:123/foo/bar.html?fox=trot#foo
protocol: http:
host: www.example.com:123
hostname: www.example.com
port: 123
pathname: /foo/bar.html
search: ?fox=trot
hash: #foo
*/

9
З огляду на те, що в оригінальному запитанні було позначено "мова-агностик", що це за мова?
MarkHu

зауважте, що це рішення вимагає існування префіксу протоколу, наприклад http://, для правильного відображення властивостей протоколу, хоста та імені хоста. В іншому випадку початок URL-адреси до першої косої риси переходить у властивість протоколу.
Олексій Аза

Я вважаю, що це хоч і просто, але набагато повільніше, ніж розбір RegEx.
demisx

Чи підтримується вона всіма браузерами?
сеан

1
Якщо ми підемо цією дорогою, ви також можете зробитиvar url = new URL(someUrl)
gman

67

Я спізнююсь на кілька років, але я здивований, що ніхто не згадав про специфікацію Уніфікованого ідентифікатора ресурсу, в якому є розділ про розбір URI з регулярним виразом . Регулярним виразом, написаним Бернерсом-Лі та співавт., Є:

^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
 12            3  4          5       6  7        8 9

Номери у другому рядку вище лише сприяють читанню; вони вказують опорні точки для кожної піддепресії (тобто для кожної парної дужки). Ми називаємо значення, відповідне для субекспресії, як $. Наприклад, узгодження вищевказаного виразу до

http://www.ics.uci.edu/pub/ietf/uri/#Related

призводить до наступних збігів субекспресії:

$1 = http:
$2 = http
$3 = //www.ics.uci.edu
$4 = www.ics.uci.edu
$5 = /pub/ietf/uri/
$6 = <undefined>
$7 = <undefined>
$8 = #Related
$9 = Related

Що того, що варто, я виявив, що мені потрібно уникнути передніх косої риски в JavaScript:

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


4
чудова відповідь! Вибір чогось із RFC, безумовно, ніколи не може погано зробити не так
відвертий

1
це не розбирає параметри запиту
Rémy DAVID

2
Це найкращий фактор. Зокрема, це стосується двох проблем, які я бачив з іншими 1: Це стосується інших протоколів, таких як ftp://і mailto://. 2: Це стосується правильно usernameі password. Ці необов'язкові поля розділені двокрапкою, подібно до імені хоста та порту, і вони збігатимуть більшість інших регексів, які я бачив. @ RémyDAVID Рядок запитів також не аналізується нормально locationоб'єктом браузера . Якщо вам потрібно проаналізувати рядок запиту, подивіться на мою крихітну бібліотеку для цього: uqs .
Штійн де Вітт

2
Ця відповідь заслуговує на більшу кількість голосів, оскільки вона охоплює майже всі протоколи.
Тяньчжень Лін

1
Він порушується, коли протокол має на увазі HTTP з ім'ям користувача / паролем (езотеричний та технічно недійсний синтаксис, я визнаю): наприклад user:pass@example.com- RFC 3986 каже:A path segment that contains a colon character (e.g., "this:that") cannot be used as the first segment of a relative-path reference, as it would be mistaken for a scheme name. Such a segment must be preceded by a dot-segment (e.g., "./this:that") to make a relative- path reference.
Метт Чемберс

33

Я знайшов, що найвища відповідь (відповідь гомеоаста) для мене не працює ідеально. Дві проблеми:

  1. Він не може обробляти номер порту.
  2. Хеш-частина зламана.

Далі йде модифікована версія:

^((http[s]?|ftp):\/)?\/?([^:\/\s]+)(:([^\/]*))?((\/\w+)*\/)([\w\-\.]+[^#?\s]+)(\?([^#]*))?(#(.*))?$

Положення деталей таке:

int SCHEMA = 2, DOMAIN = 3, PORT = 5, PATH = 6, FILE = 8, QUERYSTRING = 9, HASH = 12

Редагувати, розміщений користувачем anon:

function getFileName(path) {
    return path.match(/^((http[s]?|ftp):\/)?\/?([^:\/\s]+)(:([^\/]*))?((\/[\w\/-]+)*\/)([\w\-\.]+[^#?\s]+)(\?([^#]*))?(#(.*))?$/i)[8];
}

1
Слідкуйте за тим, щоб він не працював, якщо в URL-адресі немає домену після домену - наприклад, http://www.example.comабо якщо шлях є одним символом http://www.example.com/a.
Фернандо Коррея

11

Мені потрібен був регулярний вираз, щоб відповідати всім URL-адресам і створив цей:

/(?:([^\:]*)\:\/\/)?(?:([^\:\@]*)(?:\:([^\@]*))?\@)?(?:([^\/\:]*)\.(?=[^\.\/\:]*\.[^\.\/\:]*))?([^\.\/\:]*)(?:\.([^\/\.\:]*))?(?:\:([0-9]*))?(\/[^\?#]*(?=.*?\/)\/)?([^\?#]*)?(?:\?([^#]*))?(?:#(.*))?/

Він відповідає всім URL-адресам, будь-якому протоколу, навіть подібним URL-адресам

ftp://user:pass@www.cs.server.com:8080/dir1/dir2/file.php?param1=value1#hashtag

Результат (у JavaScript) виглядає так:

["ftp", "user", "pass", "www.cs", "server", "com", "8080", "/dir1/dir2/", "file.php", "param1=value1", "hashtag"]

URL-адреса, як

mailto://admin@www.cs.server.com

виглядає так:

["mailto", "admin", undefined, "www.cs", "server", "com", undefined, undefined, undefined, undefined, undefined] 

3
Якщо ви хочете узгодити весь домен / ip-адресу (не розділену крапками), скористайтеся цією:/(?:([^\:]*)\:\/\/)?(?:([^\:\@]*)(?:\:([^\@]*))?\@)?(?:([^\/\:]*))?(?:\:([0-9]*))?\/(\/[^\?#]*(?=.*?\/)\/)?([^\?#]*)?(?:\?([^#]*))?(?:#(.*))?/
lepe

11

Я намагався вирішити це в JavaScript, з яким слід обробляти:

var url = new URL('http://a:b@example.com:890/path/wah@t/foo.js?foo=bar&bingobang=&king=kong@kong.com#foobar/bing/bo@ng?bang');

оскільки (принаймні в Chrome) він аналізує:

{
  "hash": "#foobar/bing/bo@ng?bang",
  "search": "?foo=bar&bingobang=&king=kong@kong.com",
  "pathname": "/path/wah@t/foo.js",
  "port": "890",
  "hostname": "example.com",
  "host": "example.com:890",
  "password": "b",
  "username": "a",
  "protocol": "http:",
  "origin": "http://example.com:890",
  "href": "http://a:b@example.com:890/path/wah@t/foo.js?foo=bar&bingobang=&king=kong@kong.com#foobar/bing/bo@ng?bang"
}

Однак це не перехресний веб-переглядач ( https://developer.mozilla.org/en-US/docs/Web/API/URL ), тому я спільно скрутив це, щоб витягнути ті самі деталі, що і вище:

^(?:(?:(([^:\/#\?]+:)?(?:(?:\/\/)(?:(?:(?:([^:@\/#\?]+)(?:\:([^:@\/#\?]*))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((?:\/?(?:[^\/\?#]+\/+)*)(?:[^\?#]*)))?(\?[^#]+)?)(#.*)?

Заслуга за цей регулярний вимір є https://gist.github.com/rpflorence, який опублікував цей jsperf http://jsperf.com/url-parsing (спочатку знайдений тут: https://gist.github.com/jlong/2428561 # коментар-310066 ), хто придумав регулярний вираз, на якому спочатку грунтувався.

Запчастини в такому порядку:

var keys = [
    "href",                    // http://user:pass@host.com:81/directory/file.ext?query=1#anchor
    "origin",                  // http://user:pass@host.com:81
    "protocol",                // http:
    "username",                // user
    "password",                // pass
    "host",                    // host.com:81
    "hostname",                // host.com
    "port",                    // 81
    "pathname",                // /directory/file.ext
    "search",                  // ?query=1
    "hash"                     // #anchor
];

Також є невелика бібліотека, яка завершує її і надає параметри запитів:

https://github.com/sadams/lite-url (також доступний на шафі)

Якщо у вас є поліпшення, будь ласка, створіть запит на витягнення з додатковими тестами, і я прийму і об'єднаюся з подякою.


Це чудово, але це дійсно може бути з такою версією, яка витягує субдомени замість дублювання хоста, імені хоста. Тож якби я мав, http://test1.dev.mydomain.com/наприклад, це витягнулося б test1.dev..
Ланкімарт

Це працює дуже добре. Я шукав спосіб отримати незвичні параметри аутентифікації з URL-адрес, і це прекрасно працює.
Aaron M

6

Запропонуйте набагато зручніше для читання рішення (у Python, але стосується будь-якого регулярного виразу):

def url_path_to_dict(path):
    pattern = (r'^'
               r'((?P<schema>.+?)://)?'
               r'((?P<user>.+?)(:(?P<password>.*?))?@)?'
               r'(?P<host>.*?)'
               r'(:(?P<port>\d+?))?'
               r'(?P<path>/.*?)?'
               r'(?P<query>[?].*?)?'
               r'$'
               )
    regex = re.compile(pattern)
    m = regex.match(path)
    d = m.groupdict() if m is not None else None

    return d

def main():
    print url_path_to_dict('http://example.example.com/example/example/example.html')

Друкує:

{
'host': 'example.example.com', 
'user': None, 
'path': '/example/example/example.html', 
'query': None, 
'password': None, 
'port': None, 
'schema': 'http'
}

5

субдомен та домен є складними, оскільки субдомен може мати декілька частин, як і домен верхнього рівня, http://sub1.sub2.domain.co.uk/

 the path without the file : http://[^/]+/((?:[^/]+/)*(?:[^/]+$)?)  
 the file : http://[^/]+/(?:[^/]+/)*((?:[^/.]+\.)+[^/.]+)$  
 the path with the file : http://[^/]+/(.*)  
 the URL without the path : (http://[^/]+/)  

(Маркдаун не дуже дружній до реджексів)


2
Дуже корисно - я додав додатковий, (http(s?)://[^/]+/)щоб також захопити https
Mojowen

5

Ця вдосконалена версія повинна працювати так само надійно, як і аналізатор.

   // Applies to URI, not just URL or URN:
   //    http://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Relationship_to_URL_and_URN
   //
   // http://labs.apache.org/webarch/uri/rfc/rfc3986.html#regexp
   //
   // (?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?
   //
   // http://en.wikipedia.org/wiki/URI_scheme#Generic_syntax
   //
   // $@ matches the entire uri
   // $1 matches scheme (ftp, http, mailto, mshelp, ymsgr, etc)
   // $2 matches authority (host, user:pwd@host, etc)
   // $3 matches path
   // $4 matches query (http GET REST api, etc)
   // $5 matches fragment (html anchor, etc)
   //
   // Match specific schemes, non-optional authority, disallow white-space so can delimit in text, and allow 'www.' w/o scheme
   // Note the schemes must match ^[^\s|:/?#]+(?:\|[^\s|:/?#]+)*$
   //
   // (?:()(www\.[^\s/?#]+\.[^\s/?#]+)|(schemes)://([^\s/?#]*))([^\s?#]*)(?:\?([^\s#]*))?(#(\S*))?
   //
   // Validate the authority with an orthogonal RegExp, so the RegExp above won’t fail to match any valid urls.
   function uriRegExp( flags, schemes/* = null*/, noSubMatches/* = false*/ )
   {
      if( !schemes )
         schemes = '[^\\s:\/?#]+'
      else if( !RegExp( /^[^\s|:\/?#]+(?:\|[^\s|:\/?#]+)*$/ ).test( schemes ) )
         throw TypeError( 'expected URI schemes' )
      return noSubMatches ? new RegExp( '(?:www\\.[^\\s/?#]+\\.[^\\s/?#]+|' + schemes + '://[^\\s/?#]*)[^\\s?#]*(?:\\?[^\\s#]*)?(?:#\\S*)?', flags ) :
         new RegExp( '(?:()(www\\.[^\\s/?#]+\\.[^\\s/?#]+)|(' + schemes + ')://([^\\s/?#]*))([^\\s?#]*)(?:\\?([^\\s#]*))?(?:#(\\S*))?', flags )
   }

   // http://en.wikipedia.org/wiki/URI_scheme#Official_IANA-registered_schemes
   function uriSchemesRegExp()
   {
      return 'about|callto|ftp|gtalk|http|https|irc|ircs|javascript|mailto|mshelp|sftp|ssh|steam|tel|view-source|ymsgr'
   }


4
/^((?P<scheme>https?|ftp):\/)?\/?((?P<username>.*?)(:(?P<password>.*?)|)@)?(?P<hostname>[^:\/\s]+)(?P<port>:([^\/]*))?(?P<path>(\/\w+)*\/)(?P<filename>[-\w.]+[^#?\s]*)?(?P<query>\?([^#]*))?(?P<fragment>#(.*))?$/

З моєї відповіді на подібне запитання . Працює краще, ніж деякі з інших згаданих, оскільки вони мали деякі помилки (наприклад, не підтримують ім’я користувача / пароль, не підтримують односимвольні назви файлів, порушуються ідентифікатори фрагментів).


2

Ви можете отримати всі http / https, хост, порт, шлях, а також запит, використовуючи об'єкт Uri в .NET. просто складне завдання - розбити хост на піддомен, доменне ім’я та TLD.

Для цього не існує стандарту, і не можна просто використовувати розбір рядків або RegEx для отримання правильного результату. Спочатку я використовую функцію RegEx, але не всі URL-адреси можуть правильно проаналізувати піддомен. Практичний спосіб полягає у використанні списку TLD. Після визначення TLD для URL-адреси ліва частина - це домен, а решта - піддомен.

Однак список потребує його підтримки, оскільки можливі нові TLD. Я знаю, що зараз: publicsuffix.org підтримує останній список, і ви можете використовувати інструменти для аналізу доменних імен з коду google, щоб проаналізувати загальнодоступний список суфіксів та легко отримати піддомен, домен та TLD, використовуючи об’єкт DomainName: domainName.SubDomain, domainName .Domain and domainName.TLD.

Ця відповідь також корисна: Отримайте субдомен з URL

CaLLMeLaNN


2

Ось така, яка є повною і не покладається на жоден протокол.

function getServerURL(url) {
        var m = url.match("(^(?:(?:.*?)?//)?[^/?#;]*)");
        console.log(m[1]) // Remove this
        return m[1];
    }

getServerURL("http://dev.test.se")
getServerURL("http://dev.test.se/")
getServerURL("//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js")
getServerURL("//")
getServerURL("www.dev.test.se/sdas/dsads")
getServerURL("www.dev.test.se/")
getServerURL("www.dev.test.se?abc=32")
getServerURL("www.dev.test.se#abc")
getServerURL("//dev.test.se?sads")
getServerURL("http://www.dev.test.se#321")
getServerURL("http://localhost:8080/sads")
getServerURL("https://localhost:8080?sdsa")

Друкує

http://dev.test.se

http://dev.test.se

//ajax.googleapis.com

//

www.dev.test.se

www.dev.test.se

www.dev.test.se

www.dev.test.se

//dev.test.se

http://www.dev.test.se

http://localhost:8080

https://localhost:8080

2

Ніщо з перерахованого вище не працювало для мене. Ось що я в кінцевому підсумку використав:

/^(?:((?:https?|s?ftp):)\/\/)([^:\/\s]+)(?::(\d*))?(?:\/([^\s?#]+)?([?][^?#]*)?(#.*)?)?/

2

Мені подобається регулярний вираз, який був опублікований у "Javascript: хороші частини". Це не занадто коротко і не надто складно. Ця сторінка в github також має код JavaScript, який її використовує. Але це адаптований для будь-якої мови. https://gist.github.com/voodooGQ/4057330


1

Java пропонує клас URL, який це зробить. Об'єкти URL-адреси запиту.

З іншого боку, PHP пропонує parse_url () .


Схоже, це не розбирає субдомен?
Кріс Датроу

Аскер попросив regex. Клас URL відкриє з'єднання під час його створення.
MikeNereson

"Клас URL відкриє з'єднання під час його створення" - це неправильно, лише коли ви викликаєте такі методи, як connect (). Але це правда, що java.net.URL дещо важкий. Для цього випадку використання, java.net.URI краще.
jcsahnwaldt Reinstate Monica

1

Я б рекомендував не використовувати регекс. Виклик API, як WinHttpCrackUrl () , менш схильний до помилок.

http://msdn.microsoft.com/en-us/library/aa384092%28VS.85%29.aspx


5
А також дуже конкретна платформа.
Andir

2
Я думаю, сенс полягав у використанні бібліотеки, а не винаходити колесо. У Ruby, Python, Perl є інструменти для розбивання URL-адрес, тому захоплюйте ті замість того, щоб реалізувати поганий зразок.
Олов'яний чоловік

1

Я спробував декілька з них, які не задовольнили мої потреби, особливо найвищий голос, який не вловив URL без шляху ( http://example.com/ )

також відсутність назв груп зробило його непридатним у виконанні (або, можливо, мої навички jinja2 відсутні).

тож ця моя версія трохи змінена, і джерело є найвищою версією тут:

^((?P<protocol>http[s]?|ftp):\/)?\/?(?P<host>[^:\/\s]+)(?P<path>((\/\w+)*\/)([\w\-\.]+[^#?\s]+))*(.*)?(#[\w\-]+)?$

0

Використання http://www.fileformat.info/tool/regex.htm виразка гомеоаста чудово працює.

Але ось угода, я хочу використовувати різні схеми регексу в різних ситуаціях у своїй програмі.

Наприклад, у мене є ця URL-адреса, і у мене є перелік, який перераховує всі підтримувані URL-адреси в моїй програмі. Кожен об'єкт перерахунку має метод getRegexPattern, який повертає шаблон регулярного виразів, який потім буде використаний для порівняння з URL-адресою. Якщо конкретний шаблон регулярного вираження повертає значення true, я знаю, що ця URL-адреса підтримується моєю програмою. Отже, у кожного перерахування є власний регулярний вираз, залежно від того, де він повинен знаходитись всередині URL-адреси.

Пропозиція Hometoast чудова, але в моєму випадку я думаю, що це не допоможе (якщо тільки я не скопіюю вставку одного і того ж регулярного вираження у всіх перерахунках).

Ось чому я хотів, щоб у відповіді було подано регулярний вираз для кожної ситуації. Хоча +1 для рідного моря. ;)


0

Я знаю, що ви претендуєте на мовну агностику щодо цього, але чи можете ви сказати нам, що ви використовуєте, щоб ми знали, якими можливостями є регулярний вираз?

Якщо у вас є можливості для невлаштування сірників, ви можете змінити вираз гомеоаста так, щоб субекспресії, які ви не зацікавлені в захопленні, були налаштовані так:

(?:SOMESTUFF)

Вам все одно доведеться копіювати та вставляти (і трохи змінювати) Regex у декілька місць, але це має сенс - ви не просто перевіряєте, чи існує піддекспресія, а скоріше, чи існує вона як частина URL-адреси . Використання модифікатора, що не захоплює, для підвиразів може дати вам те, що вам потрібно, і більше нічого, що, якщо я вас правильно читаю, це те, що ви хочете.

Як і маленька маленька примітка, вираз рідного міста не повинен ставити дужки навколо 's' для 'https', оскільки він має лише один символ. Квантованці кількісно визначають один символ (або клас символів, або субекспресію) безпосередньо перед ними. Так:

https?

відповідав би "http" або "https".


0

regexp, щоб отримати URL-адресу без файлу.

url = ' http: // domain / dir1 / dir2 / somefile ' url.scan (/ ^ (http: // [^ /] +) ((?: / [^ /] +) + (? = /)) ? /? (?: [^ /] +)? $ / i) .to_s

Це може бути корисно для додавання відносного шляху до цієї URL-адреси.


0

Регекс для повного розбору досить жахливий. Я включив іменовані зворотні посилання для розбірливості та розбив кожну частину на окремі рядки, але вона все одно виглядає так:

^(?:(?P<protocol>\w+(?=:\/\/))(?::\/\/))?
(?:(?P<host>(?:(?:&(?:amp|apos|gt|lt|nbsp|quot|bull|hellip|[lr][ds]quo|[mn]dash|permil|\#[1-9][0-9]{1,3}|[A-Za-z][0-9A-Za-z]+);)|[^\/?#:]+)(?::(?P<port>[0-9]+))?)\/)?
(?:(?P<path>(?:(?:&(?:amp|apos|gt|lt|nbsp|quot|bull|hellip|[lr][ds]quo|[mn]dash|permil|\#[1-9][0-9]{1,3}|[A-Za-z][0-9A-Za-z]+);)|[^?#])+)\/)?
(?P<file>(?:(?:&(?:amp|apos|gt|lt|nbsp|quot|bull|hellip|[lr][ds]quo|[mn]dash|permil|\#[1-9][0-9]{1,3}|[A-Za-z][0-9A-Za-z]+);)|[^?#])+)
(?:\?(?P<querystring>(?:(?:&(?:amp|apos|gt|lt|nbsp|quot|bull|hellip|[lr][ds]quo|[mn]dash|permil|\#[1-9][0-9]{1,3}|[A-Za-z][0-9A-Za-z]+);)|[^#])+))?
(?:#(?P<fragment>.*))?$

Те, що вимагає, щоб воно було настільки багатослівним, це те, що крім протоколу або порту, будь-яка з частин може містити сутності HTML, що робить окреслення фрагмента досить складним. Отже, в останніх кількох випадках - хост, шлях, файл, рядок запитів та фрагмент, ми дозволяємо або будь-яку html сутність, або будь-який символ, який не є ?або #. Регекс для html-об’єкта виглядає так:

$htmlentity = "&(?:amp|apos|gt|lt|nbsp|quot|bull|hellip|[lr][ds]quo|[mn]dash|permil|\#[1-9][0-9]{1,3}|[A-Za-z][0-9A-Za-z]+);"

Коли це витягується (я використовував синтаксис вуса для його представлення), він стає трохи більш розбірливим:

^(?:(?P<protocol>(?:ht|f)tps?|\w+(?=:\/\/))(?::\/\/))?
(?:(?P<host>(?:{{htmlentity}}|[^\/?#:])+(?::(?P<port>[0-9]+))?)\/)?
(?:(?P<path>(?:{{htmlentity}}|[^?#])+)\/)?
(?P<file>(?:{{htmlentity}}|[^?#])+)
(?:\?(?P<querystring>(?:{{htmlentity}};|[^#])+))?
(?:#(?P<fragment>.*))?$

У JavaScript, звичайно, ви не можете використовувати іменовані зворотні параметри, тому регулярний вираз стає

^(?:(\w+(?=:\/\/))(?::\/\/))?(?:((?:(?:&(?:amp|apos|gt|lt|nbsp|quot|bull|hellip|[lr][ds]quo|[mn]dash|permil|\#[1-9][0-9]{1,3}|[A-Za-z][0-9A-Za-z]+);)|[^\/?#:]+)(?::([0-9]+))?)\/)?(?:((?:(?:&(?:amp|apos|gt|lt|nbsp|quot|bull|hellip|[lr][ds]quo|[mn]dash|permil|\#[1-9][0-9]{1,3}|[A-Za-z][0-9A-Za-z]+);)|[^?#])+)\/)?((?:(?:&(?:amp|apos|gt|lt|nbsp|quot|bull|hellip|[lr][ds]quo|[mn]dash|permil|\#[1-9][0-9]{1,3}|[A-Za-z][0-9A-Za-z]+);)|[^?#])+)(?:\?((?:(?:&(?:amp|apos|gt|lt|nbsp|quot|bull|hellip|[lr][ds]quo|[mn]dash|permil|\#[1-9][0-9]{1,3}|[A-Za-z][0-9A-Za-z]+);)|[^#])+))?(?:#(.*))?$

і в кожному збігу протокол є \1, хост - \2це порт \3, шлях \4, файл \5, рядок запитів \6і фрагмент \7.


0
//USING REGEX
/**
 * Parse URL to get information
 *
 * @param   url     the URL string to parse
 * @return  parsed  the URL parsed or null
 */
var UrlParser = function (url) {
    "use strict";

    var regx = /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/,
        matches = regx.exec(url),
        parser = null;

    if (null !== matches) {
        parser = {
            href              : matches[0],
            withoutHash       : matches[1],
            url               : matches[2],
            origin            : matches[3],
            protocol          : matches[4],
            protocolseparator : matches[5],
            credhost          : matches[6],
            cred              : matches[7],
            user              : matches[8],
            pass              : matches[9],
            host              : matches[10],
            hostname          : matches[11],
            port              : matches[12],
            pathname          : matches[13],
            segment1          : matches[14],
            segment2          : matches[15],
            search            : matches[16],
            hash              : matches[17]
        };
    }

    return parser;
};

var parsedURL=UrlParser(url);
console.log(parsedURL);

0

Я спробував цей регулярний вираз для розбору розділів URL:

^((http[s]?|ftp):\/)?\/?([^:\/\s]+)(:([^\/]*))?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*))(\?([^#]*))?(#(.*))?$

URL: https://www.google.com/my/path/sample/asd-dsa/this?key1=value1&key2=value2

Матчі:

Group 1.    0-7 https:/
Group 2.    0-5 https
Group 3.    8-22    www.google.com
Group 6.    22-50   /my/path/sample/asd-dsa/this
Group 7.    22-46   /my/path/sample/asd-dsa/
Group 8.    46-50   this
Group 9.    50-74   ?key1=value1&key2=value2
Group 10.   51-74   key1=value1&key2=value2

-1
String s = "https://www.thomas-bayer.com/axis2/services/BLZService?wsdl";

String regex = "(^http.?://)(.*?)([/\\?]{1,})(.*)";

System.out.println("1: " + s.replaceAll(regex, "$1"));
System.out.println("2: " + s.replaceAll(regex, "$2"));
System.out.println("3: " + s.replaceAll(regex, "$3"));
System.out.println("4: " + s.replaceAll(regex, "$4"));

Забезпечить такий вихід:
1: https: //
2: www.thomas-bayer.com
3: /
4: axis2 / services / BLZService? Wsdl

Якщо ви зміните URL на
String s = " https: //www.thomas -bayer.com?wsdl=qwerwer&ttt=888 "; вихід буде таким:
1: https: //
2: www.thomas-bayer.com
3:?
4: wsdl = qwerwer & ttt = 888

насолоджуйся ..
Йосі Лев


Не обробляє порти. Це не агностик мови.
Ohgodwhy
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.