将Javascript正则表达式转换为PHP

10

我知道这个问题已经被问了大约十几次,但这个问题并不是重复的(如果您喜欢的话可以查看其他问题);)

基本上,我有一个Javascript正则表达式,用于检查电子邮件地址,我在前端使用它进行验证,并使用CodeIgniter在后端进行双重验证,以防前端验证无法正确运行(例如浏览器问题) 。这是一个非常长的正则表达式,我不知道从哪里开始手动转换。

我基本上正在寻找一种将JS正则表达式转换为PHP正则表达式的工具 - 我在类似问题的答案中没有找到这样的工具(当然,这样的工具可能不存在)。 好吧,我撒谎了 - 其中一个建议了一个价格为39.95美元的工具,但我真的不想花这么多钱来转换单个表达式(而且,如之前提到的问题的答案所建议的那样,没有免费试用版)。

这是由aSeptik友情提供的Javascript表达式非常慷慨地提供

/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i

还有一个由CodeIgniter使用的方法,但我不想使用它,因为它不遵循相同的规则(禁止一些有效的地址):

/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix

我希望在PHP中使用与Javascript正则表达式相同的规则集.

我的前端代码认为电子邮件地址是正确的,但Codeigniter却认为不正确,这种不一致的行为自然是我想要在应用程序中解决的问题。

感谢任何和所有的提示!:D


@LarryBattle 可能是这样,但使用它的 CodeIgniter 文件是一个 .php 文件,完整的代码行是这样的:return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address)) ? FALSE : TRUE; - Chris Clower
尝试这个解决方案。http://stackoverflow.com/questions/2514810/php-email-validation-question - Larry Battle
1
有一个工具可以完美地实现这一点:RegexBuddy 可以将正则表达式从/转换为几乎任何相关的格式。 - Tim Pietzcker
1
@TimPietzcker 没错,但正如问题中提到的那样,RegexBuddy要花费40美元,我几乎无法为了转换一个正则表达式而进行这样的开支... - Chris Clower
3个回答

4
在Javascript和PHP中,正则表达式引擎存在一些差异。请查看"Comparison of regular-expression engines"文章获取理论知识以及Difference between PHP regex and JavaScript regex回答获取实际信息。
大多数情况下,你可以在PHP中使用Javascript的正则表达式模式,只需进行小幅修改即可。作为基本区别,PHP正则表达式被定义为一个字符串(或在字符串中)如下:
preg_match('/^\(?(\d{3})\)?[- ]?(\d{3})[- ]?(\d{4})$/',$telephone);

Javascript正则表达式并不是传统意义上的,它有自己的定义方式:

var ptr = new RegExp(/^\(?(\d{3})\)?[- ]?(\d{3})[- ]?(\d{4})$/);
// or
var ptr = /^\(?(\d{3})\)?[- ]?(\d{3})[- ]?(\d{4})$/;

您可以在PHP上运行正则表达式来尝试它。建议不要在Codeigniter文件中替换它,而是可以简单地扩展或替换本地库。您可以查看创建库以获取更多信息。


谢谢,但是当我把JS正则表达式放入preg_match时,出现了以下错误:Message: preg_match() [function.preg-match]: Compilation failed: PCRE does not support \L, \l, \N{name}, \U, or \u at offset 44 - Chris Clower
有时候需要进行修改 :) 请查看此主题https://dev59.com/n3A65IYBdhLWcg3w-jum - Bilal Gultekin
此外,在JS中的/\\/将会在PHP中变成'/\\\\/' - Wiktor Stribiżew

3
我能以比预期更好的方式解决这个问题。我无法转换我想使用的Javascript正则表达式(即使购买了RegexBuddy - 它很方便,但无法产生正确的转换),所以我决定在Regex Validate Email Address网站上寻找任何好的正则表达式建议。那时我发现了这个:
“得分最高的表达式目前是PHP的filter_var()使用的表达式:”
/^(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){255,})(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){65,}@)(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22))(?:\.(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-[a-z0-9]+)*\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-[a-z0-9]+)*)|(?:\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\]))$/iD

这个PHP版本与86个样本只有4个不匹配,而我之前使用的Javascript版本有8个不匹配,因此PHP版本更加准确。因此,我扩展了CodeIgniter的Form_validation库,改用return filter_var($str, FILTER_VALIDATE_EMAIL);

但是,它能在Javascript中使用吗?

var pattern = new RegExp(/^(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){255,})(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){65,}@)(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22))(?:\.(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-[a-z0-9]+)*\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-[a-z0-9]+)*)|(?:\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\]))$/i);

太棒了!非常有效!我不仅得到了前端和后端验证之间所需的一致性,还在此过程中获得了更准确的正则表达式。双倍收获!

感谢所有提供建议的人!


“无法生成适当的转换”是什么意思?您是否使用命令 从JavaScript //操作符粘贴导入,并在使用选项卡上选择了 PHP(preg),并选择了 If / else分支是否匹配(部分)字符串 选项? - Tim Pietzcker
@TimPietzcker 也许我没有做对 - 我将它粘贴在顶部并使用下拉菜单 JavaScript,然后在底部选择了 Use 选项卡,最后选择了语言 PHP (preg),带有 If/else branch whether the regex matches (part of) a string。也许我应该使用 从 JavaScript // 操作符粘贴。当我将其放置在 PHP 中时,结果没有抛出任何错误,但是没有匹配的内容; 一切都返回为 false。 - Chris Clower

1
今天有一个网站https://regex101.com/存在,你可以将一个JS正则表达式转换成PHP或其他语言。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接