寻找技巧以更好地理解 Perl 兼容的正则表达式运算符和语法

Looking for tips to better understand Perl Compatible Regular Expression operators and syntax

我的问题是关于 Perl 兼容的正则表达式运算符和语法。我已经了解了“/hello/”的基本语法,而 /i 表示不区分大小写。我在 jotform.com 上对此进行了研究,并将对其进行研究,直到我有更深入的了解。但我希望有人可以让我先了解我在下面发布的 (2) PCRE 中的 Perl 语法和运算符。它们都致力于防止用户以文本区域的形式发布链接,但在语法和运算符上有很大不同。只是想知道一个正则表达式是否优于另一个。哪个最好,为什么?

更新:经过几个月的实时测试,PCRE 1 似乎无法阻止 PHP 联系表中的 URL。 PCRE 2 似乎确实可以防止 PHP 联系人表单中的 URL 在同一实时测试时间段内出现。

下面的 2 个正则表达式最初是在 How to prevent spam URLs in a PHP contact form

处找到的

有比 PCRE 2 更好的正则表达式吗?任何帮助或建议将不胜感激。

谢谢。

<?php

//PCRE 1 - Does not work to prevent URLs 

if (preg_match( '/www\.|http:|https:\/\/[a-z0-9_]+([\-\.]{1}[a-z_0-9]+)*\.[_a-z]{2,5}'.'((:[0-9]{1,5})?\/.*)?$/i', $_POST['message']))
{
echo 'error please remove URLs';
}else
{....

//PCRE 2 - Does work to prevent URLs 

if (preg_match("/\b(?:(?:https?|ftp|http):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i",$_POST['message']))
{
echo 'error please remove URLs';
}else
{....

?>

为了提供答案以便将此页面标记为已解决(而不是放弃),我将对第二种模式进行改进。

/\b(?:(?:https?|ftp|http):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i

可以改写为:

\b(?:(?:f|ht)tps?:\/\/)[-\w+&@#\/%?=~|!:,.;]*[-\w+&@#\/%=~|]
  • 第一段使用交替匹配 httpshttpftpsftp 作为“整个单词”(\b) (|) 和零或一量词 (?)。您的原始模式需要 url 的“协议”部分存在,因此我不会更改模式逻辑。
  • 尽管子域在有效 url 中不是必需的,但您的模式中的子域需要 www.,并且可以使用 www. 以外的有效值。我将更改此段的模式逻辑,使子域可选且更灵活。
  • 字符class(白名单字符)合并了www.中的字符,因此可以从模式中省略文字匹配。
  • 我通过使用 \w 减少了你的两个字符 classes 的长度 -- 它包括所有字母数字字符(大写和小写)以及下划线。
  • 下面是匹配内容的演示:https://regex101.com/r/TP16iB/1 -- you will find that a valid url like www.example.com is not matched by your preferred pattern nor my pattern. To overcome this, you could hardcode the www. as the required subdomain and make the protocol optional, but then you would not be matching variable subdomains. So you see, this is a bit of a rabbit hole where you will need to weigh up how much time you wish to invest versus what your application really needs. Be warned, the more accurate your pattern becomes, so grows its total length/convolution.
    \b(?:(?:(?:f|ht)tps?:\/\/)|(?:www\.))\[-\w+&@#\/%?=~|!:,.;\]*\[-\w+&@#\/%=~|\]