Regex仅匹配用于phpbb的本地URL

Regex仅匹配用于phpbb的本地URL,php,regex,phpbb3,Php,Regex,Phpbb3,我正在用phpBB3制作留言板。有一个内置的功能,它接受帖子中的所有URL,然后呈现为链接。我想让它只有本地链接是可点击的 phpbb3在帖子文本上使用正则表达式,每次匹配都会将其更改为链接: if ($somestuff){ // matches a xxxx://aaaaa.bbb.cccc. ... $magic_url_match[] = '#(^|[\n\t (>.])(' . "[a-z]$scheme*:/{2}(?:(?:[a-z0-9\-._~!$&'($inli

我正在用phpBB3制作留言板。有一个内置的功能,它接受帖子中的所有URL,然后呈现为链接。我想让它只有本地链接是可点击的

phpbb3在帖子文本上使用正则表达式,每次匹配都会将其更改为链接:

if ($somestuff){
// matches a xxxx://aaaaa.bbb.cccc. ...
$magic_url_match[] = '#(^|[\n\t (>.])(' . "[a-z]$scheme*:/{2}(?:(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?" . ')#ie';
$magic_url_replace[] = "make_clickable_callback(MAGIC_URL_FULL, '\$1', '\$2', '', '$class')";

// matches a "www.xxxx.yyyy[/zzzz]" kinda lazy URL thing
$magic_url_match[] = '#(^|[\n\t (>])(' . "www\.(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})+(?::\d*)?(?:/(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?" . ')#ie';
$magic_url_replace[] = "make_clickable_callback(MAGIC_URL_WWW, '\$1', '\$2', '', '$class')";
}
return preg_replace($magic_url_match, $magic_url_replace, $text);

我如何重写这些正则表达式,使它们只匹配我域上的链接?另外,教自己正则表达式的最好方法是什么?

这是第一种,一节一节地分解。即使这样做也不是小事

(
    ^
|
    [\n\t (>.]
)
好的,这里我们只需要“行的开头,或者在换行符、制表符、空格、大于、句点之后。只需锚定正则表达式

(
    [a-z]$scheme*:/{2}
这简直是疯了。
$scheme
可能包含
http
,这意味着这个正则表达式与
http://
匹配。为什么有人会使用
/{2}
而不是
/
,我无法猜测

    (?:
        (?:
            [a-z0-9\-._~!$&'($inline*+,;=:@|]+
        |
            %[\dA-F]{2}
        )+
    |
这将匹配一系列字符,可能是URL中合法的字符。值得注意的是
$inline
PHP变量–猜不出它包含什么–以及第二个可选的
%[\dA-F]{2}
。它匹配空间的
%20
等内容。
%
符号在匹配中不合法(或在URL中)

这里同样重要的是,
/
是不合法的。因此,这不能引用目录,只能引用域。这很可能是您想要更改的部分,以便只匹配您网站的适当域

不过,为了完整起见,下面是其余部分

        [0-9.]+
    |
或者,我们可以有一系列数字和句点——一个IP地址。考虑到这个正则表达式有多么复杂,我很惊讶他没有选择
(?:\d{1,3}\){3}\d{1,3}

        \[
        [a-z0-9.]+
        :
        [a-z0-9.]+
        :
        [a-z0-9.:]+
        \]
    )
这是我们的最后一个选择;我认为这是针对IPv6的。无论如何,这是一系列用冒号分隔的十六进制数字。它要求这些数字在方括号内,我觉得这很奇怪,特别是对于一个论坛软件,它大量使用这些数字作为标记

    (?:
        :
        \d*
    )?
在这里,我们可以选择在冒号后面加上一些数字。也就是说,这是用于带有端口的URL

    (?:
        /
        (?:
            [a-z0-9\-._~!$&'($inline*+,;=:@|]+
        |
            %[\dA-F]{2}
        )*
    )*
好的,这里我们得到了子目录,如开头的
/
所示。否则,这是相同的“合法URL字符”匹配

最后,通过
传递的内容获取
,由
\?
表示,以及链接到中间页面锚的URL,由
\
表示

底线: 本节:

    [a-z]$scheme*:/{2}
    (?:
        (?:
            [a-z0-9\-._~!$&'($inline*+,;=:@|]+
        |
            %[\dA-F]{2}
        )+
    |
        [0-9.]+
    |
        \[
        [a-z0-9.]+
        :
        [a-z0-9.]+
        :
        [a-z0-9.:]+
        \]
    )
应替换为以下内容:

    [a-z]$scheme*://
    www\.example\.com
或许

    [a-z]$scheme*://
    (?:
        www\.example\.com
    |
        192\.168\.0\.1
    |
        ::ffff:192\.168\.0\.1
    )
<> p>域名和IP地址匹配你的网站。显然,你将不得不删除断线和缩进。我会为你做的,但我认为这几乎不值得,因为你会很难找到一个地方,你把你的域名在这一切。 您可能希望为子域或忽略
www.
或其他内容的人添加一些正则表达式

您可能还希望删除以下内容:

    (?:
        :
        \d*
    )?
因为您可能不希望人们链接到域上的其他端口


第二个看起来有大致相同的结构;正如评论所说,它只是得到了缺少协议标识符的URL。

天哪,Molly!!!这就是我所说的正则表达式-我没有说我喜欢正则表达式!如果我甚至能弄清楚正则表达式的哪一部分用于http://,哪一部分是www,哪一部分是域名,我可以我想我应该这样做。*另请参阅和,以获取一些有用的工具,或者更好的教程。我正在努力完成第一个教程。我可以评论一下,有人在协议后使用了
/{2}
而不是
/
双斜杠吗?他们疯了吗?
    (?:
        :
        \d*
    )?