如何匹配文本中的URI?
如何在文本块中发现URI?
想法是将这些文本运行转换为链接。如果仅考虑http(s)和ftp(s)方案,这将非常简单。但是,我猜测一般问题(考虑tel,mailto和其他URI方案)要复杂得多(如果可能的话)。
我希望在Cif中提供解决方案。谢谢你。
解决方案
回答
对于许多协议,我们可以只搜索"://"而不加引号。虽然不确定其他人。
回答
某些内容是否为URI取决于上下文。通常,它们唯一的共同点是它们以" scheme_name:"开头。方案名称可以是任何名称(以合法字符为准)。但是其他字符串也包含冒号,而不是URI。
因此,我们需要确定感兴趣的方案。通常,对于我们关心的每种方案,我们都可以搜索" scheme_name:",然后是字符,直到空格为止。不幸的是,URI可以包含空格,因此,如果将它们嵌入文本中,则可能会造成歧义。我们无法采取任何措施来解决编写文本的人必须解决的歧义。 URI可以选择包含在<>中。不过,大多数人都不会这样做,因此认识到这种格式只会偶尔有所帮助。
URI的Wikipedia文章列出了相关的RFC。
[编辑添加:使用正则表达式完全验证URI是一场噩梦,即使我们以某种方式找到或者创建了正确的URI,也将非常庞大,并且难以注释和维护。幸运的是,如果我们正在做的是突出显示链接,那么我们可能不需要关心奇数假阳性,因此我们无需进行验证。只需查找" http://"," mailto:\ S * @"等)
回答
这是带有正则表达式的代码片段,可满足各种需求:
http://snipplr.com/view/6889/regular-expressions-for-uri-validationparsing/
回答
如果我们还希望匹配" something.tld",这并不容易,因为普通文本将具有该模式的许多实例,但是如果我们仅希望匹配以方案开头的URI,则可以尝试使用此正则表达式(对不起,我不知道如何将其插入C#)
(http|https|ftp|mailto|tel):\S+[/a-zA-Z0-9]
我们可以在此处添加更多方案,并且要考虑到最后一个字符不是无效的字符(例如,如通常的字符串" http://www.example.com"那样,它会与方案匹配直到下一个空格字符)。 )
回答
下面的perl regexp应该可以解决问题。 chave perl正则表达式吗?
/\w+:\/\/[\w][\w\.\/]*/
回答
正则表达式可能证明是一个很好的起点,尽管众所周知,URI和URL很难与单个模式匹配。
为了说明这一点,最简单的模式看起来相当复杂(用Perl 5表示法):
\ w +:\ / {2} [\ d \ w-] +(\。[\ d \ w-] +)*(?:(?:\ / [^ \ s /] *))*
这将匹配http:// example.com / foo / bar-baz
和
ftp://192.168.0.1/foo/file.txt
但至少会造成以下问题:
- mailto:[email protected](不匹配-没有
//
,但存在@
) - 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模式感兴趣,我想可能是URI的定义是使用Type-2语法完成的,而正则表达式只能解析Type-3语法中的语言。
回答
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; },