简体   繁体   English

将 Javascript 正则表达式转换为 PHP

[英]Converting Javascript Regex to PHP

I know this question has been asked about a dozen times, but this one is not technically a dupe (check the others if you like) ;)我知道这个问题已经被问过十几次了,但这个问题在技术上并不是一个骗局(如果你愿意,请检查其他人);)

Basically, I have a Javascript regex that checks email addresses which I use for front-end validation, and I use CodeIgniter to double check on the back end, in case the validation on the front end fails to run properly (browser issues, for instance.) It's QUITE a long regular expression, and I have no idea where to begin converting it by hand.基本上,我有一个 Javascript 正则表达式来检查我用于前端验证的电子邮件地址,并且我使用 CodeIgniter 对后端进行双重检查,以防前端验证无法正常运行(例如浏览器问题) .) 这是一个很长的正则表达式,我不知道从哪里开始手动转换它。

I'm pretty much looking for a tool that converts JS regexes to PHP regexes - I haven't found one in any of the answers to similar questions (of course, it's possible that such a tool doesn't exist.) Okay, I lied - one of them suggested a tool that costs $39.95, but I really don't want to spend that much to convert a single expression (and no, there isn't a free trial as suggested by the answer to the aforementioned question.)我正在寻找一种将 JS 正则表达式转换为 PHP 正则表达式的工具- 我在类似问题的任何答案中都没有找到一个(当然,这样的工具可能不存在。)好的,我撒谎了 - 其中一个人建议使用一种成本为 39.95 美元的工具,但我真的不想花那么多钱来转换单个表达式(不,没有上述问题的答案所建议的免费试用。)

Here's the Javascript expression , graciously provided by aSeptik :这是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

And the one used by CodeIgniter, which I don't want to use because it doesn't follow the same rules (disallows some valid addresses):而 CodeIgniter 使用的那个,我不想使用,因为它不遵循相同的规则(不允许一些有效地址):

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

I want to use the same rules set by the Javascript regex in PHP .我想在 PHP 中使用由 Javascript 正则表达式设置的相同规则

Having this sort of inconsistency where my front-end code is saying that the email address is okay, and then Codeigniter says it isn't, is of course the behavior I'm trying to fix in my application.在我的前端代码说电子邮件地址没问题,然后 Codeigniter 说它不是这样的情况下,这种不一致当然是我试图在我的应用程序中修复的行为。

Thanks for any and all tips!感谢您提供任何提示! :D :D

There are some differences between regex engines in Javascript and PHP. Javascript 和 PHP 中的正则表达式引擎之间存在一些差异。 Please check Comparison of regular-expression engines article for theoretical and Difference between PHP regex and JavaScript regex answer for practical information.有关实用信息,请查看正则表达式引擎的比较文章以了解理论和PHP 正则表达式与 JavaScript 正则表达式之间的差异答案。

Most of the time, you can use Javascript regex patterns in PHP with small modifications.大多数情况下,您只需稍加修改即可在 PHP 中使用 Javascript 正则表达式模式。 As a fundamental difference, PHP regex is defined as a string (or in a string) like this:作为一个根本区别,PHP regex 被定义为一个字符串(或在一个字符串中),如下所示:

preg_match('/^\(?(\d{3})\)?[- ]?(\d{3})[- ]?(\d{4})$/',$telephone);

Javascript regex is not, it's defined in its own way: Javascript 正则表达式不是,它以自己的方式定义:

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

You can give it a try by running the regex on PHP.您可以通过在 PHP 上运行正则表达式来尝试一下。 As a recommendation, do not replace it in Codeigniter files, you can simply extend or replace native library.建议不要在 Codeigniter 文件中替换它,您可以简单地扩展或替换本机库。 You can check Creating Libraries out for more information.您可以查看创建库以获取更多信息。

I was able to solve this in a better-than-expected manner.我能够以比预期更好的方式解决这个问题。 I was unable to convert the Javascript regex that I wanted to use (even after purchasing RegexBuddy - it'll come in handy, but it was not able to produce a proper conversion), so I decided to go looking on the Regex Validate Email Address site to see if they had any recommendations anywhere for good regexes.我无法转换我想使用的 Javascript 正则表达式(即使在购买了 RegexBuddy 之后 - 它会派上用场,但无法产生正确的转换),所以我决定去查看Regex 验证电子邮件地址网站,看看他们是否有任何关于好的正则表达式的建议。 That's when I found this:那时我发现了这个:

"The expression with the best score is currently the one used by PHP's filter_var() ": “目前得分最高的表达式是 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

It matches with only 4/86 errors, while the Javascript one I was using matches with 8/86 errors, so the PHP one is a little more accurate.它只匹配 4/86 错误,而我使用的 Javascript 匹配有 8/86 错误,所以 PHP 更准确一些。 So, I extended the CodeIgniter Form_validation library to instead use return filter_var($str, FILTER_VALIDATE_EMAIL);因此,我扩展了 CodeIgniter Form_validation库,改为使用return filter_var($str, FILTER_VALIDATE_EMAIL); . .

...But does it work in Javascript? ...但它在 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);

Zing!赞! Works like a charm!奇迹般有效! Not only did I get the consistency I was looking for between front and back end validation, but I also got a more accurate regex in the process.我不仅在前端和后端验证之间获得了我正在寻找的一致性,而且在这个过程中我还获得了更准确的正则表达式。 Double win!双赢!

Thank you to all those who provided suggestions!感谢所有提供建议的人!

今天有网站https://regex101.com/可以将一个 JS 正则表达式转换为 PHP 或其他一些语言。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM