Regex以匹配URL中资源之前的路径

本文关键字:路径 资源 URL Regex | 更新日期: 2023-09-27 17:58:13

为了让每个人都能理解所涉及的词汇,URL的一般结构如下:

  http   ://   www.a.com   /  path/to/resource.html  ?  query=value  #  fragment
{scheme} ://  {authority}  /         {path}          ?   {query}     #  {fragment}

路径由路径和资源组成,在path/to/resource.html的情况下,路径是path/to/,资源是resource.html

贫穷、讨厌和粗鲁:
HTML,正如它在野外发现的那样,可能是贫穷的、令人讨厌的和野蛮的,尽管通常远远不够短。在这个贫穷、肮脏和野蛮的世界里,尽管URL应该遵守标准,但直播链接本身可能是贫穷、肮脏、野蛮的。因此,考虑到这一点,我向您介绍问题。。。

问题:

我试图创建一个正则表达式来从URL的路径中删除资源,当网页中有一个链接是相对路径时,这是必要的。例如:

  1. 我访问www.domain.com/path/to/page1.html
  2. 有一个到/page2.html的相对链接
  3. 从URL中删除/page1.html
  4. /page2.html附加到www.domain.com/path/to

结果:在www.domain.com/path/to/page2.html

我被卡在第三步了

我已经隔离了路径和资源,但现在我想将两者分开。我试图想出的正则表达式如下:'z([^'/]'.[^'/])

在C#中,相同的正则表达式是:"''z([^/]''.[^/])"

regex在英语中的意思是:匹配字符串的末尾,该字符串包括由句点分隔的所有字符,只要这些字符不是斜杠

我试过那个正则表达式,但目前它失败得很惨。什么是实现上述结果的适当查询。

以下是一些示例案例:

/path/to/resource.html=>/path/to/resource.html
/pa.th/to/resource.html=>/pa.th/to/resource.html
/路径/to/resource.html/=>/path/to/resource.html/
/*我#$>78zxdc.78&(!~=>/*I#$>/78zxdc.78&(!~

谢谢你的帮助!

Regex以匹配URL中资源之前的路径

System.Uri

var uri = new Uri("http://www.domain.com/path/to/page1.html?query=value#fragment");
Console.WriteLine(uri.Scheme); // http
Console.WriteLine(uri.Host); // www.domain.com
Console.WriteLine(uri.AbsolutePath); // /path/to/page1.html
Console.WriteLine(uri.PathAndQuery); // /path/to/page1.html?query=value
Console.WriteLine(uri.Query); // ?query=value
Console.WriteLine(uri.Fragment); // #fragment
Console.WriteLine(uri.Segments[uri.Segments.Length - 1]); // page1.html
for (var i = 0 ; i < uri.Segments.Length ; i++)
{
    Console.WriteLine("{0}: {1}", i, uri.Segments[i]);
    /*
    Output
    0: /
    1: path/
    2: to/
    3: page1.html
    */
}

您的正则表达式引擎支持变长外观吗?如果是这样,您可以使用它来展望(因此排除)末尾的非斜杠字符:

.*/(?=[^/]*$)

或者,使用捕获组,路径将是组1,资源分组2

(.*/)([^/]*$)

非正则表达式算法如下:

  1. 存储最后斜杠的pos
  2. 来自0的长度为pos+1的子体

注意:我故意忽略了这里的.。它们有什么意义?在HTML中,如果您有一个不以斜杠结尾的路径,则相对路径将是相对于最后一部分的父级的。因此,就本讨论而言,没有点的部分基本上是一个无扩展的资源。

当Uri类已经为您完成了几乎所有的工作时,我无法想象您为什么要使用正则表达式。要获得最后一部分(即,将资源与路径分离),只需使用String.LastIndexOfString.Substring即可。例如:

Uri myUri;
if (!Uri.TryCreate(linkString, UriKind.RelativeOrAbsolute, out myUri))
{
    // some kind of error.
}
int pos = myUri.AbsolutePath.LastIndexOf('/');
++pos;
string resource = myUri.AbsolutePath.Substring(pos);    

我毫不怀疑你可以用正则表达式来做这些事情。我怀疑这是一场胜利。正如你所说,当你在网络上爬行时,你发现的网址可能非常糟糕。我的爬虫花了相当大的精力来规范一些看起来非常狂野的url。我经常碰到http://example.com/dir/subdir/subsubdir/../../dir///moretrash/resource.html这样的东西。你不会相信(如果你在网上爬行,也许你会相信)我看到的奇怪的逃跑。Uri类很好地解析了url,这样我就可以对其进行规范化。

我的经验是,创建Uri实例的时间与规范URL所需的时间相比相形见绌:unescape、剥离片段和会话标识符、识别和避免代理和爬网程序陷阱、删除无关斜杠和路径导航(即/.//../)等。我只是不知道在哪里使用正则表达式,即使它比CCD_ 22快,也会提高我的运行时间。我非常怀疑它是否能像Uri.TryCreate一样出色地解析我在野外发现的URL。

要提取URI的资源部分,可以使用:

^                  # matches start of str
.*                 # greedy match up to the last '/'
'/                 # literal '/'
(                  # start capture of resource part
   [^'/'?'#]*      # zero or more chars except '/', '?', and '#'
)                  # end capture
(?:                # start optional group - query part
  '?               # literal '?' for optional query
  .+?              # non-greedy match for any chars
)?                 # end of optional group
(?:                # start of optional group - fragment part
  '#               # literal '#' for optional fragment
  .+?              # non-greedy match for any chars
)?                 # end of optional group
$

我认为也许你应该在'/'上拆分字符串,而不是拘泥于生成正则表达式。你也看了吗http://msdn.microsoft.com/en-us/library/ms952653.aspx