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的路径中删除资源,当网页中有一个链接是相对路径时,这是必要的。例如:
- 我访问
www.domain.com/path/to/page1.html
- 有一个到
/page2.html
的相对链接 - 从URL中删除
/page1.html
- 将
/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&(!~
谢谢你的帮助!
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:
(.*/)([^/]*$)
非正则表达式算法如下:
- 存储最后斜杠的
pos
- 来自0的长度为
pos+1
的子体
注意:我故意忽略了这里的.
。它们有什么意义?在HTML中,如果您有一个不以斜杠结尾的路径,则相对路径将是相对于最后一部分的父级的。因此,就本讨论而言,没有点的部分基本上是一个无扩展的资源。
当Uri类已经为您完成了几乎所有的工作时,我无法想象您为什么要使用正则表达式。要获得最后一部分(即,将资源与路径分离),只需使用String.LastIndexOf
和String.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