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

Pau*_*aul -3 regex

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

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

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

谢谢

Rol*_*man 6

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

#...actual regex goes here...#
Run Code Online (Sandbox Code Playgroud)

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

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

#...actual regex goes here...#..flags go here..
Run Code Online (Sandbox Code Playgroud)

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

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

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

(...group...)
Run Code Online (Sandbox Code Playgroud)

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

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

(http|https|ftp)
Run Code Online (Sandbox Code Playgroud)

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

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

://
Run Code Online (Sandbox Code Playgroud)

这些不是特殊字符,任何非特殊字符只是匹配自己.

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

([A-Z0-9][A-Z0-9_-]*(?:.[A-Z0-9][A-Z0-9_-]*)+)
Run Code Online (Sandbox Code Playgroud)

在它里面,我们看到一个括号内的表达式:

[A-Z0-9]
Run Code Online (Sandbox Code Playgroud)

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

A-Z
Run Code Online (Sandbox Code Playgroud)

表示字符A到Z(以及介于两者之间的任何东西)和

0-9
Run Code Online (Sandbox Code Playgroud)

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

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

这又是另一个字符类:

[A-Z0-9_-]
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

[A-Z0-9][A-Z0-9_-]*
Run Code Online (Sandbox Code Playgroud)

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

正则表达式的以下位是这样的:

(?:.[A-Z0-9][A-Z0-9_-]*)+
Run Code Online (Sandbox Code Playgroud)

我认为这是尝试匹配域部分.所以,如果你说:

https://mail.google.com
Run Code Online (Sandbox Code Playgroud)

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

(\.[A-Z0-9][A-Z0-9_-]*)+
Run Code Online (Sandbox Code Playgroud)

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

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

:?(d+)?
Run Code Online (Sandbox Code Playgroud)

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

:?(\d+)?
Run Code Online (Sandbox Code Playgroud)

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

http://domain.server.extension:8080/
Run Code Online (Sandbox Code Playgroud)

正则表达式的这部分将匹配:8080(假设您修复了d +事物).最后,我们看到了

/?
Run Code Online (Sandbox Code Playgroud)

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

所以,总而言之,我不认为这与"链接"匹配,而是匹配URL的初始部分.要匹配整个URL,您需要更多,至少我没有看到任何表达式可以匹配可能出现在正确URL中的路径,资源,散列和查询位.