首页 / 知识

关于文本匹配:如何匹配文本中的URI?

2023-04-16 12:54:00

关于文本匹配:如何匹配文本中的URI?

How to match URIs in text?

如何在文本块中发现URI?

这样做的目的是将这种文本运行转换为链接。 如果仅考虑http和ftp方案,这将非常简单。 但是,我猜测一般问题(考虑tel,mailto和其他URI方案)要复杂得多(如果可能的话)。

如果可能,我希望使用C#解决方案。 谢谢。


正则表达式可能证明是一个很好的起点,尽管众所周知,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: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模式感兴趣,我想可能是URI的定义是使用Type-2语法完成的,而正则表达式只能解析Type-3语法中的语言。


某些内容是否为URI取决于上下文。通常,它们唯一的共同点是它们以" scheme_name:"开头。方案名称可以是任何名称(以合法字符为准)。但是其他字符串也包含冒号而不是URI。

因此,您需要确定感兴趣的方案。通常,对于您关心的每种方案,您都可以搜索" scheme_name:",然后是字符,直到空格为止。不幸的是,URI可以包含空格,因此,如果将它们嵌入文本中,则可能会造成歧义。您无法采取任何措施解决歧义-撰写文本的人将不得不对其进行修复。 URI可以选择包含在<>中。不过,大多数人都不会这样做,因此认识到这种格式只会偶尔有所帮助。

URI的Wikipedia文章列出了相关的RFC。

[编辑添加:使用正则表达式完全验证URI是一个噩梦-即使您以某种方式找到或创建了正确的URI,也将非常庞大且难以注释和维护。幸运的是,如果您正在做的是突出显示链接,那么您可能不需要关心奇数假阳性,因此您无需进行验证。只需查找" http://"," mailto:\ S * @"等]


Ubiquity的URL工具执行以下操作:

1
2
3
4
5
6
7
8
9
10
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;
},

如果您还希望匹配" something.tld",这并不容易,因为普通文本将具有该模式的许多实例,但是如果您仅希望匹配以方案开头的URI,则可以尝试使用此正则表达式(对不起,我不知道如何将其插入C#)

1
(http|https|ftp|mailto|tel):\\S+[/a-zA-Z0-9]

您可以在此处添加更多方案,并且要考虑到最后一个字符不是无效的字符(例如,如通常的字符串" http://www.example.com"那样,它会与方案匹配直到下一个空格字符)。 )


这是带有正则表达式的代码片段,可满足各种需求:

http://snipplr.com/view/6889/regular-expressions-for-uri-validationparsing/


对于许多协议,您可以只搜索"://"而不加引号。虽然不确定其他。


下面的perl regexp应该可以解决问题。 C#是否具有perl正则表达式?

1
/\\w+:\\/\\/[\\w][\\w\\.\\/]*/


文本方案链接运行

最新内容

相关内容

猜你喜欢