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

Posted

技术标签:

【中文标题】寻找提示以更好地理解 Perl 兼容的正则表达式运算符和语法【英文标题】:Looking for tips to better understand Perl Compatible Regular Expression operators and syntax 【发布时间】:2020-09-01 19:22:36 【问题描述】:

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

更新:经过几个月的现场测试,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
....

?>

【问题讨论】:

经过几个月的现场测试,PCRE 1 似乎无法阻止 PHP 联系表单中的 URL。 PCRE 2 似乎确实可以在同一实时测试时间段内阻止 PHP 联系表单中的 URL。 【参考方案1】:

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

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

可以改写为:

\b(?:(?:f|ht)tps?:\/\/)[-\w+&@#\/%?=~|!:,.;]*[-\w+&@#\/%=~|]
第一段匹配 httpshttpftpsftp 作为“整个单词”(\b),使用交替 (|) 和零或一个量词 (@987654331 @)。您的原始模式需要 url 的“协议”部分存在,因此我不会更改模式逻辑。 您的模式中的子域需要 www.,尽管有效 url 中不需要子域并且可以使用除 www. 之外的有效值。我将更改此段的模式逻辑,以使子域可选且更灵活。 字符类(列入白名单的字符)包含www. 中的字符,因此可以从模式中省略文字匹配。 我通过使用\w 减少了两个字符类的长度——它包括所有字母数字字符(大写和小写)以及下划线。 下面是匹配内容的演示:https://regex101.com/r/TP16iB/1——您会发现像www.example.com 这样的有效 url 与您的首选模式和我的模式都不匹配。为了克服这个问题,您可以将www. 硬编码为所需的子域并使协议可选,但这样您就不会匹配可变子域。所以你看,这有点像兔子洞,你需要权衡你希望投入多少时间与你的应用程序真正需要什么。请注意,您的模式越准确,其总长度/卷积也会增加。\b(?:(?:(?:f|ht)tps?:\/\/)|(?:www\.))\[-\w+&amp;@#\/%?=~|!:,.;\]*\[-\w+&amp;@#\/%=~|\]

【讨论】:

以上是关于寻找提示以更好地理解 Perl 兼容的正则表达式运算符和语法的主要内容,如果未能解决你的问题,请参考以下文章

有人可以帮助我更好地理解正则表达式中的零或一,并可能在同一个正则表达式语句中嵌套另一个

请对 POSIX 风格和兼容 Perl 风格两种正则表达式的主要函数进行类比说明

ereg

PHP -- Perl风格正则表达式

PHP 正则表达式匹配 preg_match 与 preg_match_all 函数

PHP的正则表达式