获取URL的一部分(正则表达式)

时间:2020-03-05 18:43:14  来源:igfitidea点击:

给定URL(单行):
http://test.example.com/dir/subdir/file.html

如何使用正则表达式提取以下部分:

  • 子域(测试)
  • 域(example.com)
  • 没有文件的路径(/ dir / subdir /)
  • 文件(file.html)
  • 文件的路径(/dir/subdir/file.html)
  • 不含路径的网址(http://test.example.com)
  • (添加我们认为有用的其他任何内容)

即使输入以下URL,该正则表达式也应能正常工作:
http://example.example.com/example/example/example.html

谢谢你。

解决方案

回答

A single regex to parse and breakup a
  full URL including query parameters
  and anchors e.g.
  
  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 positions:
  
  url: RegExp['$&'], 
  
  protocol:RegExp.,
  
  host:RegExp., 
  
  path:RegExp.,
  
  file:RegExp., 
  
  query:RegExp.,
  
  hash:RegExp.

然后,我们可以轻松地进一步解析主机(以"。"分隔)。

我要做的是使用这样的东西:

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

进一步分析"其余"尽可能具体。在一个正则表达式中这样做有点疯狂。

回答

这不是直接的答案,但是大多数Web库都具有完成此任务的功能。该函数通常被称为类似于" CrackUrl"的东西。如果存在这样的功能,请使用它,几乎可以保证它比任何手工编写的代码都更加可靠和高效。

回答

请尝试以下方法:

^((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

回答

子域和域很困难,因为子域可以包含多个部分,顶级域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对正则表达式不是很友好)

回答

使用http://www.fileformat.info/tool/regex.htm,hometoast的正则表达式效果很好。

但是这很重要,我想在程序中的不同情况下使用不同的正则表达式模式。

例如,我有这个URL,并且我有一个枚举列出了程序中所有受支持的URL。枚举中的每个对象都有一个方法getRegexPattern,该方法返回正则表达式模式,然后将其用于与URL比较。如果特定的正则表达式模式返回true,那么我知道我的程序支持此URL。因此,每个枚举都有自己的正则表达式,具体取决于它在URL中的位置。

Hometoast的建议很好,但就我而言,我认为这无济于事(除非我在所有枚举中复制粘贴相同的正则表达式)。

这就是为什么我想要答案分别针对每种情况给出正则表达式的原因。虽然为家庭敬酒+1. ;)

回答

我知道我们在声称与语言无关,但是可以告诉我们我们在使用什么,以便我们知道我们拥有哪些正则表达式功能吗?

如果我们具有非捕获匹配的功能,则可以修改hometoast的表达式,以便对捕获不感兴趣的子表达式进行如下设置:

(?:SOMESTUFF)

我们仍然必须将Regex复制并粘贴(并稍加修改)到多个位置,但这是有道理的-我们不仅要检查子表达式是否存在,还要检查它是否作为URL的一部分存在。对子表达式使用non-captureing修饰符可以为我们提供所需的内容,仅此而已,如果我正确地阅读了内容,这就是我们想要的。

就像一个很小的音符一样,hometoast的表达不需要在" s"的括号中加上" https",因为他在那里只有一个字符。量词量化直接在它们前面的一个字符(或者字符类或者子表达式)。所以:

https?

可以匹配" http"或者" https"。

回答

Java提供了可以执行此操作的URL类。查询URL对象。

附带说明一下,PHP提供了parse_url()。

回答

我发现投票率最高的答案(hometoast的答案)对我而言并不完美。两个问题:

  • 它无法处理端口号。
  • 哈希部分损坏。

以下是修改后的版本:

^((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];
}

回答

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

根据我对类似问题的回答。由于存在一些错误(例如,不支持用户名/密码,不支持单字符文件名,片段标识符被破坏),因此它们比其他提到的工具工作得更好。

回答

regexp以获取不带文件的URL路径。

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

将相对路径添加到此url可能很有用。

回答

我们可以使用.NET中的Uri对象获取所有http / https,主机,端口,路径以及查询。
唯一困难的任务是将主机分为子域,域名和TLD。

没有标准这样做,不能简单地使用字符串解析或者RegEx来产生正确的结果。首先,我使用RegEx函数,但并非所有URL都能正确解析该子域。练习方法是使用TLD列表。在定义了URL的TLD之后,左侧部分是域,其余部分是子域。

但是,该列表需要维护,因为可以使用新的TLD。我知道的当前时间是publicsuffix.org,它维护着最新的列表,我们可以使用Google代码中的域名解析器工具来解析公共后缀列表,并通过使用DomainName对象轻松地获取子域,域和TLD:domainName.SubDomain,domainName .Domain和domainName.TLD。

这个答案也有帮助:
从URL获取子域

卡伦·梅兰

回答

我建议不要使用正则表达式。像WinHttpCrackUrl()这样的API调用不太容易出错。

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

回答

此改进的版本应与解析器一样可靠地工作。

// 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
   //  matches scheme (ftp, http, mailto, mshelp, ymsgr, etc)
   //  matches authority (host, user:pwd@host, etc)
   //  matches path
   //  matches query (http GET REST api, etc)
   //  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'
   }

回答

遗憾的是,这不适用于某些URL。以这个为例:http://www.example.org/&value=329

&value = 329也不

甚至根本没有任何参数(简单的URL)!

我知道正则表达式期望使用一些非常复杂/长的URL,但是它也应该能够在简单的URL上工作,对吗?