การรับบางส่วนของ URL (Regex)


134

ระบุ 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. (เพิ่มสิ่งอื่น ๆ ที่คุณคิดว่ามีประโยชน์)

regex ควรทำงานได้อย่างถูกต้องแม้ว่าฉันจะป้อน URL ต่อไปนี้:

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

นี่ไม่ใช่คำตอบโดยตรง แต่เว็บไลบรารีส่วนใหญ่มีฟังก์ชันที่ช่วยให้งานนี้สำเร็จ ฟังก์ชันนี้มักเรียกว่าสิ่งที่คล้ายกับCrackUrl. หากมีฟังก์ชั่นดังกล่าวให้ใช้มันเกือบจะรับประกันได้ว่าน่าเชื่อถือและมีประสิทธิภาพมากกว่าโค้ดที่สร้างขึ้นด้วยมือใด ๆ
Konrad Rudolph

7
โปรดอธิบายให้เราทราบว่าเหตุใดจึงต้องทำสิ่งนี้ด้วยนิพจน์ทั่วไป ถ้าเป็นการบ้านก็พูดแบบนั้นเพราะนั่นคือข้อ จำกัด ของคุณ มิฉะนั้นจะมีโซลูชันเฉพาะภาษาที่ดีกว่าการใช้ regex
Andy Lester

1
ลิงก์ไปยังตัวอย่างแรกและตัวอย่างสุดท้ายเสีย
คนดีบุก

คุณสามารถดูวิธีการแตกรูปแบบโดเมน TLD พอร์ตและเส้นทางการสืบค้นได้ที่นี่stackoverflow.com/questions/9760588/…
Paolo Rovelli

คำตอบ:


153

regex เดียวเพื่อแยกวิเคราะห์และแยก 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,

แบบสอบถาม: RegExp $ 7,

แฮช: RegExp $ 8

จากนั้นคุณสามารถแยกวิเคราะห์โฮสต์ ("." คั่น) ได้อย่างง่ายดาย

สิ่งที่ฉันจะทำคือใช้สิ่งนี้:

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

แยกวิเคราะห์ 'ส่วนที่เหลือ' เพิ่มเติมให้เฉพาะเจาะจงมากที่สุด การทำใน regex เดียวก็บ้าไปหน่อย


4
รหัสลิงก์nippets.joyent.com/posts/show/523ใช้งานไม่ได้ ณ วันที่ 20 ต.ค. 53
W3Max

19
ปัญหาคือส่วนนี้: (.*)?เนื่องจากดาวคลีนยอมรับ 0 ขึ้นไปแล้ว?ส่วน (0 หรือ 1) จึงทำให้สับสน ฉันแก้ไขโดยเปลี่ยน(.*)?เป็น(.+)?. คุณยังสามารถลบ?
rossipedia

3
สวัสดี Dve ฉันได้ปรับปรุงอีกเล็กน้อยในการแยกexample.comจาก url เช่นhttp://www.example.com:8080/....Here ไป:^((http[s]?|ftp):\/\/)?\/?([^\/\.]+\.)*?([^\/\.]+\.[^:\/\s\.]{2,3}(\.[^:\/\s\.]{2,3})?(:\d+)?)($|\/)([^#?\s]+)?(.*?)?(#[\w\-]+)?$
mnacos

4
และพิสูจน์ได้ว่าไม่มี regexp ที่สมบูรณ์แบบนี่คือการแก้ไขทันที:^((http[s]?|ftp):\/\/)?\/?([^\/\.]+\.)*?([^\/\.]+\.[^:\/\s\.]{2,3}(\.[^:\/\s\.]{2,3})?)(:\d+)?($|\/)([^#?\s]+)?(.*?)?(#[\w\-]+)?$
mnacos

2
ฉันแก้ไข regex นี้เพื่อระบุทุกส่วนของ URL (เวอร์ชันปรับปรุง) - โค้ดใน Python ^((?P<scheme>[^:/?#]+):(?=//))?(//)?(((?P<login>[^:]+)(?::(?P<password>[^@]+)?)?@)?(?P<host>[^@/?#:]*)(?::(?P<port>\d+)?)?)?(?P<path>[^?#]*)(\?(?P<query>[^#]*))?(#(?P<fragment>.*))? code คุณแสดงโค้ดนี้ในการทำงานบนpythex.org
arannasousa

82

ฉันรู้ว่าฉันไปปาร์ตี้ช้า แต่มีวิธีง่ายๆในการให้เบราว์เซอร์แยกวิเคราะห์ URL สำหรับคุณโดยไม่ต้องใช้ regex:

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
เนื่องจากคำถามเดิมติดแท็ก "language-agnostic" นี่คือภาษาอะไร
MarkHu

โปรดทราบว่าโซลูชันนี้ต้องการคำนำหน้าโปรโตคอลเช่นhttp://สำหรับการแสดงคุณสมบัติโปรโตคอลโฮสต์และชื่อโฮสต์ที่ถูกต้อง มิฉะนั้นจุดเริ่มต้นของ url จนกว่าเครื่องหมายทับแรกจะไปที่คุณสมบัติโปรโตคอล
Oleksii Aza

ฉันเชื่อว่านี่เป็นเรื่องง่าย แต่ช้ากว่าการแยกวิเคราะห์ RegEx มาก
demisx

รองรับทุกเบราว์เซอร์หรือไม่
ฌอน

1
ถ้าเราจะทำแบบนี้คุณก็ทำได้เช่นกันvar url = new URL(someUrl)
gman

73

ฉันไม่กี่ปีที่ผ่านมาสายไปงานเลี้ยง แต่ผมแปลกใจที่ไม่มีใครได้กล่าวถึง Uniform Resource Identifier เปคมีส่วนที่เกี่ยวกับยูริแยกด้วยสีหน้าปกติ นิพจน์ทั่วไปที่เขียนโดย 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:

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


4
คำตอบที่ดี! การเลือกบางสิ่งจาก RFC ไม่สามารถทำให้สิ่งที่ผิดพลาดเกิดขึ้นได้อย่างแน่นอน
Frankster

1
สิ่งนี้ไม่ได้แยกวิเคราะห์พารามิเตอร์การค้นหา
Rémy DAVID

2
นี่คือ afaict ที่ดีที่สุด โดยเฉพาะนี้ adresses สองปัญหาฉันได้เห็นกับคนอื่น ๆ : 1: ข้อเสนอนี้อย่างถูกต้องกับโปรโตคอลอื่น ๆ เช่นและftp:// : ข้อเสนอนี้อย่างถูกต้องกับและ ช่องที่เป็นทางเลือกเหล่านี้คั่นด้วยเครื่องหมายจุดคู่เช่นเดียวกับชื่อโฮสต์และพอร์ตและมันจะเดินทางขึ้นไปยัง regexes อื่น ๆ ที่ฉันเคยเห็น @ RémyDAVIDสตริงการสืบค้นยังไม่ได้รับการแยกวิเคราะห์โดยวัตถุเบราว์เซอร์ตามปกติ หากคุณต้องการที่จะแยกสตริงแบบสอบถามมีลักษณะที่ห้องสมุดเล็ก ๆ ของฉันสำหรับว่า: uqs mailto://2usernamepasswordlocation
Stijn de Witt

2
คำตอบนี้สมควรได้รับคะแนนโหวตมากขึ้นเนื่องจากครอบคลุมโปรโตคอลทั้งหมดค่อนข้างมาก
Tianzhen Lin

2
มันหยุดทำงานเมื่อโปรโตคอลบอกเป็นนัย 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.
Matt Chambers

33

ฉันพบว่าคำตอบที่ได้รับการโหวตสูงสุด (คำตอบของ 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

แก้ไขโพสต์โดยผู้ใช้ 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
Fernando Correia

11

ฉันต้องการ Expression ปกติเพื่อให้ตรงกับ 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]+))?))?)?)?((?:\/?(?:[^\/\?#]+\/+)*)(?:[^\?#]*)))?(\?[^#]+)?)(#.*)?

เครดิตสำหรับ regex นี้ไปที่https://gist.github.com/rpflorenceผู้โพสต์ jsperf นี้http://jsperf.com/url-parsing (พบที่นี่: https://gist.github.com/jlong/2428561 # comment-310066 ) ผู้ที่สร้าง regex ซึ่งเดิมขึ้นอยู่กับ.

ชิ้นส่วนอยู่ในลำดับนี้:

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)

หากคุณมีการปรับปรุงโปรดสร้างคำขอดึงพร้อมการทดสอบเพิ่มเติมและฉันจะยอมรับและรวมเข้าด้วยขอบคุณ


นี่เป็นสิ่งที่ยอดเยี่ยม แต่สามารถทำได้กับเวอร์ชันเช่นนี้ที่ดึงโดเมนย่อยออกมาแทนที่จะเป็นโฮสต์ที่ซ้ำกันชื่อโฮสต์ ดังนั้นถ้าผมมีตัวอย่างเช่นมันจะดึงออกhttp://test1.dev.mydomain.com/ test1.dev.
Lankymart

นี้ได้ผลดีมาก ฉันกำลังมองหาวิธีแยกพารามิเตอร์การตรวจสอบสิทธิ์ที่ผิดปกติออกจาก URL และมันก็ใช้ได้ดี
Aaron M

6

เสนอโซลูชันที่อ่านง่ายกว่ามาก (ใน Python แต่ใช้กับ regex ใดก็ได้):

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://[^/]+/)  

(Markdown ไม่เป็นมิตรกับ regexes)


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'
   }

5

ลองทำดังต่อไปนี้:

^((ht|f)tp(s?)\:\/\/|~/|/)?([\w]+:\w+@)?([a-zA-Z]{1}([\w\-]+\.)+([\w]{2,5}))(:[\d]{1,5})?((/?\w+/)+|/?)(\w+\.[\w]{3,4})?((\?\w+=\w+)?(&\w+=\w+)*)?

รองรับ HTTP / FTP โดเมนย่อยโฟลเดอร์ไฟล์ ฯลฯ

ฉันพบมันจากการค้นหาโดย Google อย่างรวดเร็ว:

http://geekswithblogs.net/casualjim/archive/2005/12/01/61722.aspx


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 object ใน. NET งานที่ยากคือการแบ่งโฮสต์ออกเป็นโดเมนย่อยชื่อโดเมนและ TLD

ไม่มีมาตรฐานในการทำเช่นนั้นและไม่สามารถใช้การแยกวิเคราะห์สตริงหรือ RegEx เพื่อให้ได้ผลลัพธ์ที่ถูกต้อง ตอนแรกฉันใช้ฟังก์ชัน RegEx แต่ URL บางส่วนไม่สามารถแยกวิเคราะห์โดเมนย่อยได้อย่างถูกต้อง วิธีปฏิบัติคือใช้รายการ TLD หลังจากกำหนด TLD สำหรับ URL แล้วส่วนด้านซ้ายคือโดเมนและส่วนที่เหลือคือโดเมนย่อย

อย่างไรก็ตามรายการดังกล่าวจำเป็นต้องดูแลรักษาเนื่องจาก TLD ใหม่เป็นไปได้ ช่วงเวลาปัจจุบันที่ฉันรู้คือ publicsuffix.org รักษารายการล่าสุดและคุณสามารถใช้เครื่องมือแยกวิเคราะห์ชื่อโดเมนจากรหัส google เพื่อแยกวิเคราะห์รายการต่อท้ายสาธารณะและรับโดเมนย่อยโดเมนและ TLD ได้อย่างง่ายดายโดยใช้วัตถุ DomainName: domainName.SubDomain, domainName .Domain และ 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: The Good Parts" ไม่สั้นเกินไปและไม่ซับซ้อนเกินไป หน้านี้บน github ยังมีโค้ด JavaScript ที่ใช้ด้วย แต่จะปรับให้เข้ากับภาษาใดก็ได้ https://gist.github.com/voodooGQ/4057330


1

Java เสนอคลาส URL ที่จะทำสิ่งนี้ Query URL Objects

สังเกตด้านบน, PHP มีparse_url ()


ดูเหมือนว่านี่จะไม่ได้แยกวิเคราะห์โดเมนย่อยออกไป?
Chris Dutrow

Asker ถาม regex คลาส URL จะเปิดการเชื่อมต่อเมื่อคุณสร้าง
MikeNereson

"คลาส URL จะเปิดการเชื่อมต่อเมื่อคุณสร้าง" ซึ่งไม่ถูกต้องเฉพาะเมื่อคุณเรียก method เช่น connect () แต่เป็นเรื่องจริงที่ java.net.URL ค่อนข้างหนัก สำหรับกรณีการใช้งานนี้ java.net.URI จะดีกว่า
jcsahnwaldt Reinstate Monica

1

ฉันอยากจะแนะนำว่าอย่าใช้ regex การเรียก 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/ )

การขาดชื่อกลุ่มทำให้ใช้ไม่ได้ใน ansible (หรือบางทีทักษะ jinja2 ของฉันขาด)

ดังนั้นนี่คือเวอร์ชันของฉันที่แก้ไขเล็กน้อยโดยมีแหล่งที่มาเป็นเวอร์ชันที่ได้รับการโหวตสูงสุดที่นี่:

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

0

ใช้http://www.fileformat.info/tool/regex.htm regex ของ hometoast ใช้งานได้ดี

แต่นี่คือข้อตกลงฉันต้องการใช้รูปแบบ regex ที่แตกต่างกันในสถานการณ์ต่างๆในโปรแกรมของฉัน

ตัวอย่างเช่นฉันมี URL นี้และฉันมีการแจงนับที่แสดงรายการ URL ที่สนับสนุนทั้งหมดในโปรแกรมของฉัน แต่ละออบเจ็กต์ในการแจงนับมีเมธอด getRegexPattern ที่ส่งคืนรูปแบบ regex ซึ่งจะใช้เพื่อเปรียบเทียบกับ URL หากรูปแบบนิพจน์ทั่วไปคืนค่าเป็นจริงแสดงว่าฉันรู้ว่า URL นี้ได้รับการสนับสนุนโดยโปรแกรมของฉัน ดังนั้นการแจงนับแต่ละครั้งจึงมี regex ของตัวเองขึ้นอยู่กับว่าควรดูที่ใดภายใน URL

คำแนะนำของ Hometoast นั้นดีมาก แต่ในกรณีของฉันฉันคิดว่ามันคงไม่ช่วยอะไร (เว้นแต่ฉันจะคัดลอกและวาง regex เดียวกันในการแจงนับทั้งหมด)

นั่นคือเหตุผลที่ฉันต้องการคำตอบเพื่อให้ regex สำหรับแต่ละสถานการณ์แยกกัน แม้ว่า +1 สำหรับ hometoast ;)


0

ฉันรู้ว่าคุณอ้างว่าไม่เชื่อเรื่องพระเจ้าเรื่องภาษา แต่คุณช่วยบอกเราได้ไหมว่าคุณกำลังใช้อะไรเพื่อให้เรารู้ว่าคุณมีความสามารถของ regex อย่างไร

หากคุณมีความสามารถสำหรับการจับคู่แบบไม่จับภาพคุณสามารถปรับเปลี่ยนนิพจน์ของ hometoast เพื่อให้นิพจน์ย่อยที่คุณไม่สนใจในการจับภาพได้รับการตั้งค่าดังนี้:

(?:SOMESTUFF)

คุณจะยังคงมีการคัดลอกและวาง (และปรับเปลี่ยนเล็กน้อย) Regex เข้าไปในสถานที่ต่างๆ แต่นี้ทำให้รู้สึก - ที่คุณอยู่ไม่ได้เป็นเพียงการตรวจสอบเพื่อดูว่า subexpression ที่มีอยู่ แต่ถ้ามันมีอยู่เป็นส่วนหนึ่งของ URL การใช้ตัวแก้ไขแบบไม่จับภาพสำหรับนิพจน์ย่อยสามารถให้สิ่งที่คุณต้องการและไม่มีอะไรเพิ่มเติมซึ่งถ้าฉันอ่านคุณถูกต้องก็เป็นสิ่งที่คุณต้องการ

เช่นเดียวกับข้อความเล็ก ๆ น้อย ๆ การแสดงออกของ hometoast ไม่จำเป็นต้องใส่วงเล็บรอบ 's' สำหรับ 'https' เนื่องจากเขามีเพียงอักขระเดียวในนั้น Quantifiers จะหาจำนวนอักขระหนึ่งตัว (หรือคลาสอักขระหรือนิพจน์ย่อย) ที่อยู่ข้างหน้าโดยตรง ดังนั้น:

https?

จะจับคู่ "http" หรือ "https" ได้ดี


0

regexp เพื่อรับเส้นทาง URL โดยไม่มีไฟล์

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

จะมีประโยชน์สำหรับการเพิ่มเส้นทางสัมพัทธ์ไปยัง URL นี้


0

regex ในการแยกวิเคราะห์แบบเต็มนั้นค่อนข้างน่ากลัว ฉันได้รวมการอ้างอิงชื่อกลับเพื่อความชัดเจนและแยกแต่ละส่วนออกเป็นบรรทัดแยกกัน แต่ก็ยังคงมีลักษณะดังนี้

^(?:(?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>.*))?$

สิ่งที่ต้องการให้เป็นแบบ verbose คือยกเว้นโปรโตคอลหรือพอร์ตส่วนใดส่วนหนึ่งอาจมีเอนทิตี HTML ซึ่งทำให้การแบ่งส่วนย่อยค่อนข้างยุ่งยาก ดังนั้นในบางกรณีสุดท้าย - โฮสต์เส้นทางไฟล์สตริงการสืบค้นและชิ้นเราอนุญาตให้ทั้งนิติบุคคล html ที่ใด ๆ หรือตัวอักษรใด ๆ ที่ไม่ได้เป็นหรือ? #regex สำหรับเอนทิตี 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 คุณไม่สามารถใช้การอ้างอิงย้อนกลับที่มีชื่อได้ดังนั้น regex จึงกลายเป็น

^(?:(\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

ฉันลอง regex นี้เพื่อแยกวิเคราะห์พาร์ติชัน 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

0

ฉันสร้างอันนี้ อนุญาตมากที่จะไม่ตรวจสอบ url juste แบ่งมัน

^((http[s]?):\/\/)?([a-zA-Z0-9-.]*)?([\/]?[^?#\n]*)?([?]?[^?#\n]*)?([#]?[^?#\n]*)$

  • คู่ที่ 1: โปรโตโคลแบบเต็มด้วย: // (http หรือ https)
  • คู่ที่ 2: โปรโตโคลที่ไม่มี: //
  • คู่ที่ 3: โฮสต์
  • คู่ที่ 4: กระสุน
  • คู่ที่ 5: พารามิเตอร์
  • คู่ที่ 6: สมอ

งาน

http://
https://
www.demo.com
/slug
?foo=bar
#anchor

https://demo.com
https://demo.com/
https://demo.com/slug
https://demo.com/slug/foo
https://demo.com/?foo=bar
https://demo.com/?foo=bar#anchor
https://demo.com/?foo=bar&bar=foo#anchor
https://www.greate-demo.com/

ผิดพลาด

#anchor#
?toto?

-2
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=qwer&ttt=888 "; ผลลัพธ์จะเป็นดังนี้
1: https: //
2: www.thomas-bayer.com
3
4: wsdl = qwerwer & ttt = 888

เพลิน..
โยซี่เลฟ


ไม่จัดการพอร์ต ไม่เข้าใจเรื่องภาษา
Ohgodwhy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.