链接的正则表达式 - 有助于理解它

时间:2012-03-01 20:29:41

标签: regex

你怎么看这个正则表达式?

#(http|https|ftp)://([A-Z0-9][A-Z0-9_-]*(?:.[A-Z0-9][A-Z0-9_-]*)+):?(d+)?/?#i

这是链接的正则表达式,但我很难理解它

谢谢

2 个答案:

答案 0 :(得分:6)

根据您所使用的语言,正则表达式需要分隔符。似乎在这里使用了#(井号或哈希)。所以,

#...actual regex goes here...#

在javascript中你需要正斜杠(/..../).

某些正则表达式引擎允许您传递影响匹配过程的标志。这些出现在结束分隔符之后:

#...actual regex goes here...#..flags go here..

在你的例子中,有一个标志,我和我猜这意味着:"不区分大小写" (我是不敏感的)。根据正则表达式引擎,您可以使用影响可用于实际正则表达式的语法的标志(例如,点可以匹配任何字符或除换行符之外的任何字符,具体取决于传递标志),标志影响如何匹配完成(例如,在javascript ag中表示全局标志,这意味着匹配字符串内的任何位置,并保留状态),这些标志确定是否允许空格作为正则表达式内的缩进。并且一些有一个m标志,指示是否将逐行应用正则表达式,或者整个文本。 AFAIK没有标准的标志集,请检查您的正则表达式引擎文档。

如果你有多个标志,你只需将它们连接成一串标志,然后将它们放在结束分隔符之后。

现在为实际的正则表达式。首先,从括号表达式开始:

(...group...)

这也称为一组。在许多正则表达式引擎中,这些组具有特殊含义,因为当找到匹配时,您可以使用特殊变量访问与组内表达式匹配的文本位(或者有时,匹配作为数组返回,其中每个元素代表一个团体)。如果您可以访问组内的位,则称为"捕获组"。

在这种特殊情况下,小组使用"交替"或"选择"这由|表示(管)。管道是正则表达式语法的一部分,意味着"或"。所以,

(http|https|ftp)

表示:匹配" http",或者如果不匹配," https",如果不匹配," ftp&# 34 ;.这也带来了使用括号的另一个原因:在所有特殊正则表达式语法运算符中,管道具有最低优先级,因此括号不会出现在那里,它意味着:匹配" http"或" https"或" ftp://...etc"

到目前为止,我们已经看过这些"特殊字符":| (管道)和(和)。之后我们得到

://

这些不是特殊字符,任何非特殊字符都只是匹配。

然后我们得到另一个组,几乎构成正则表达式的其余部分:

([A-Z0-9][A-Z0-9_-]*(?:.[A-Z0-9][A-Z0-9_-]*)+)

在其中,我们看到一个括号内的表达式:

[A-Z0-9]

括号[和]是特殊的,表示"字符类"。还有其他方法可以表示字符类,但在所有情况下,字符类都匹配单个字符。哪个角色取决于班级的性质。在这种情况下,使用两个范围定义类:

A-Z

表示字符A到Z(以及其间的任何内容)和

0-9

表示字符0到9(以及介于两者之间的任何内容)。

基本上,[A-Z0-9]匹配任何字母数字字符。 请注意,范围边界之间的破折号只是这些括号内表达式中的特殊字符。矛盾的是,括号内的破折号也可以简单地表示破折号,如果它不能被解释为范围。

还有另一个字符类:

[A-Z0-9_-]

几乎与之前的相同,它只是添加了下划线和短划线。最后一个破折号不能解释为范围分隔符,因此它只是表示破折号。此字符类将匹配任何字母数字字符以及下划线和短划线。

此类后跟*(星号),这是一个表示基数的特殊字符。基数指定前一个元素可能出现的频率。这些是常见的基数:

  • *(星号)表示零次或多次。
  • ?(问题掩码)表示零或一次。
  • +(加)表示一次或多次。

现在整个比特开始有意义了:

[A-Z0-9][A-Z0-9_-]*

表示:以一个字母数字字符开头的序列,可选地后跟一个"字符串#34;字符(即字母数字,短划线和下划线)。

正则表达式的下列是:

(?:.[A-Z0-9][A-Z0-9_-]*)+

我认为这是在尝试匹配域名部分。所以如果你说:

https://mail.google.com

.google.com位将与此部分匹配。最初的(?:位用于告诉正则表达式引擎不创建"反向引用"。这不是我的据点,也许其他人可以解释。但该组的其他成员非常清楚,与我们之前看到的相似。我认为有一个错误:在括号中的角色类之前出现的点(。)通常意味着"匹配任何角色"或"匹配任何非换行符#34;而不是"匹配文字点"。通常,如果您需要文字点,则需要将其转义。这将是javascript中的语法,我认为perl:

(\.[A-Z0-9][A-Z0-9_-]*)+

(注意点之前的反斜杠表示文字点)

正则表达式的最后几位似乎是尝试匹配端口号:

:?(d+)?

然而,d+位可能是错误的:现在它匹配"一个或多个d"。应该是:

:?(\d+)?

含义:可选地匹配冒号(:),可选地后跟一堆数字。 \d也是一个字符类,但是是预定义的一个。我认为大多数正则表达式引擎使用\d来表示数字,但是您应该检查引擎的文档以查看确切的约定。所以说:

http://domain.server.extension:8080/

正则表达式的这部分匹配:8080(如果你修复了d +的东西)。 最后,我们看到了

/?

意味着可以通过正斜杠任意跟随整个事物。

所以,总而言之,我并不认为这与#34;链接相匹配,而是匹配网址的初始部分。要匹配整个网址,您需要更多,至少我没有看到任何表达式可以匹配可能出现在正确网址中的路径,资源,哈希和查询位。

答案 1 :(得分:2)

如果你说你理解它有困难,那就意味着你尝试了某些东西并被困在某个地方?

请询问更具体的问题。

我可以为您提供一些关键字,您可以更轻松地查找它们,这是一个好地方regular-expressions.info

(http|https|ftp)是一个替代

[A-Z0-9]是一个字符类

*+?是量词

(...)是(捕获)组,(?:...)是非捕获组

开头和结尾的#是正则表达式分隔符,最后的i是修饰符/选项(与案例无关)。

最后的(d+)?将匹配一个或多个(可选)字母“d”。这很奇怪。我假设它应该是(\d+)?,这将是一个或多个(可选)数字。