[regex] URL의 일부 가져 오기 (정규식)

주어진 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



답변

쿼리 매개 변수 및 앵커를 포함하여 전체 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 [ ‘$ &’],

프로토콜 : RegExp. $ 2,

호스트 : RegExp. $ 3,

경로 : RegExp. $ 4,

파일 : RegExp. $ 6,

query : RegExp. $ 7,

해시 : RegExp. $ 8

그런 다음 호스트를 더욱 쉽게 구문 분석 할 수 있습니다 ( ‘.’구분).

어떻게 내가 할 것이라고는이 같은 사용 무언가이다 :

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

추가 구문 분석 ‘나머지’는 가능한 한 구체적이어야합니다. 하나의 정규식에서하는 것은 약간 미친 것입니다.


답변

나는 파티에 늦었다는 것을 알고 있지만 정규 표현식없이 브라우저가 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
*/


답변

나는 파티에 몇 년 늦었지만, 아무도 URI ( Uniform Resource Identifier) ​​사양 에 정규식으로 URI 구문 분석에 대한 섹션 이 있다고 언급 한 것이 놀랍다 . Berners-Lee 등이 작성한 정규식은 다음과 같습니다.

^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
 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에서 슬래시를 피해야한다는 것을 알았습니다.

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


답변

나는 가장 높은 투표 응답 (hometoast의 답변)이 완벽하게 작동하지 않는다는 것을 알았습니다. 두 가지 문제 :

  1. 포트 번호를 처리 할 수 ​​없습니다.
  2. 해시 부분이 손상되었습니다.

다음은 수정 된 버전입니다.

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

부품의 위치는 다음과 같습니다.

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

익명 사용자가 게시 한 편집 :

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


답변

모든 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] 


답변

나는 이것을 자바 스크립트로 해결하려고 노력했다.

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 # comment-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 (또는 bower에서도 사용 가능)

개선이 있다면 더 많은 테스트로 끌어 오기 요청을 작성하십시오. 감사합니다.


답변

훨씬 더 읽기 쉬운 솔루션을 제안하십시오 (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'
}