如何在文本块中识别URI?
这个想法是将这些文本转化为链接。如果只考虑http(s)和ftp(s)协议,这很容易实现; 但是,我猜想一般问题(考虑tel,mailto和其他URI协议)会更加复杂(如果可能的话)。
如果可能的话,我希望使用C#解决方案。谢谢。
如何在文本块中识别URI?
这个想法是将这些文本转化为链接。如果只考虑http(s)和ftp(s)协议,这很容易实现; 但是,我猜想一般问题(考虑tel,mailto和其他URI协议)会更加复杂(如果可能的话)。
如果可能的话,我希望使用C#解决方案。谢谢。
\w+:\/{2}[\d\w-]+(\.[\d\w-]+)*(?:(?:\/[^\s/]*))*
http://example.com/foo/bar-baz
和ftp://192.168.0.1/foo/file.txt
,但至少会对以下内容造成问题:
mailto:support@stackoverflow.com
(不匹配-没有//
,但存在@
)ftp://192.168.0.1.2
(匹配,但数字太多,因此它不是有效的URI)ftp://1000.120.0.1
(匹配,但IP地址需要介于0和255之间的数字,因此它不是有效的URI)nonexistantscheme://obvious.false.positive
http://www.google.com/search?q=uri+regular+expression
(匹配,但查询不是
我认为这是80:20法则的一个例子。如果你想捕捉大部分内容,那么我建议找到一个好的正则表达式,如果你自己写不出来的话。如果你正在查看从相当受控制的来源(例如机器生成的)提取的文本,则这将是最佳操作方法。
如果您绝对必须捕获遇到的每个URI,并且您正在查看来自网络的文本,则我认为我会寻找任何带有冒号的单词,例如\s(\w:\S+)\s
。一旦您有了适合作为URI的候选项,然后将其传递给您正在使用的库的URI类中的真实URI解析器。某物是否为URI取决于上下文。一般来说,它们唯一的共同点是以"scheme_name:"开头。方案名称可以是任何内容(符合法律字符)。但其他字符串也包含有冒号而不是URI。
所以你需要决定你感兴趣的方案。通常情况下,你可以搜索每个你关心的方案中跟随空格的字符,然后在其后添加"scheme_name:"。不幸的是,URI可能包含空格,因此如果它们嵌入到文本中,则有潜在的歧义。你无法解决这种歧义-撰写文本的人必须修复它。URI可以选择用<>括起来。大多数人不会这样做,因此识别这种格式只会偶尔有所帮助。
维基百科上的URI文章列出了相关的RFC。
[编辑添加:使用正则表达式完全验证URI非常困难-即使你找到或创建一个正确的,它也会非常庞大,难以评论和维护。幸运的是,如果你只是突出显示链接,你可能不需要验证偶尔的误报,因此你不需要验证。只需搜索"http://"、"mailto:\S*@"等即可]
如果你想匹配"something.tld",那就不太容易了,因为普通文本中会有很多这种模式的实例。但是,如果你只想匹配以一个scheme开头的URI,你可以尝试使用这个正则表达式(抱歉,我不知道如何在C#中使用它)
(http|https|ftp|mailto|tel):\S+[/a-zA-Z0-9]
您可以在那里添加更多的方案,它将匹配方案直到下一个空格字符,考虑到最后一个字符不是无效的(例如,在非常常见的字符串 "http://www.example.com." 中)
Ubiquity URL工具的功能如下:
findURLs: function(text) {
var urls = [];
var matches = text.match(/(\S+\.{1}[^\s\,\.\!]+)/g);
if (matches) {
for each (var match in matches) {
urls.push(match);
}
}
return urls;
},
对于许多协议,您可以只搜索“://”(不带引号)。不过其他的我就不确定了。
这里是一个带有正则表达式的代码片段,适用于各种需求:
http://snipplr.com/view/6889/regular-expressions-for-uri-validationparsing/
/\w+:\/\/[\w][\w\.\/]*/