简体   繁体   English

Safari 的正则表达式后视替代方案

[英]Regex lookbehind alternative for Safari

I have implemented this regex for matching a string for validation purposes: ^(?<serialCode>[a-zA-Z0-9]{0,3})(?:(?<serialMarket>[a-zA-Z]{1,2})(?<serialSuffix>(?<=^.{5})[a-zA-Z0-9]*)?)?我已经实现了这个正则表达式来匹配字符串以进行验证: ^(?<serialCode>[a-zA-Z0-9]{0,3})(?:(?<serialMarket>[a-zA-Z]{1,2})(?<serialSuffix>(?<=^.{5})[a-zA-Z0-9]*)?)?

I'm using it in JS using match() function like this:我在 JS 中使用match() function 像这样:

 const regex = '^(?<serialCode>[a-zA-Z0-9]{0,3})(?:(?<serialMarket>[a-zA-Z]{1,2})(?<serialSuffix>(?<=^.{5})[a-zA-Z0-9]*)?)?'; const stringToMatch = 'EV1FOO12FF344'; const result = stringToMatch.match(new RegExp(regex)); console.log(result); // returns each group for match and also the full match

What basically this does is that it's doing the following step by step validations and creating groups:基本上,它所做的是它正在执行以下逐步验证并创建组:

  • first 3 characters should be only alphanumeric characters前 3 个字符只能是字母数字字符
  • characters 4 and 5 should be only letters字符 4 和 5 只能是字母
  • all the rest of the characters should be alphanumeric characters字符的所有 rest 应为字母数字字符

This validation is done for every typed value in an input field, character by character .对输入字段中的每个键入值逐个字符地进行此验证。

Using lookbehind as you can see above, this works perfectly for my purposes in Chrome and Mozilla Firefox browsers.正如您在上面看到的那样,使用lookbehind,这非常适合我在 Chrome 和 Mozilla Firefox 浏览器中的用途。

The problem : lookbehind (in current case (?<=^.{5}) ) is not supported on Safari browser as per this link: https://caniuse.com/js-regexp-lookbehind We receive this error in this case: Invalid regular expression: invalid group specifier name问题 lookbehind浏览器不支持lookbehind(在当前情况下(?<=^.{5}) : Invalid regular expression: invalid group specifier name

Is there any alternative to that lookbehind so the regex will work in the exact same way?是否有任何替代方法可以使正则表达式以完全相同的方式工作?

I have the link where I tested some values for exemplification: https://regex101.com/r/fPmiTk/1 There you can see how the strings are matched and how the groups are created.我有一个链接,我在其中测试了一些示例值: https://regex101.com/r/fPmiTk/1在那里您可以看到字符串是如何匹配的以及如何创建组。

I doubt there is a way with a single regex with no lookbehind or conditionals support thus I suggest the following approach combining regex and additional programming logic:我怀疑有没有一种没有后视或条件支持的单一正则表达式的方法,因此我建议采用以下结合正则表达式和附加编程逻辑的方法:

 var texts = ['abcfobar','abc33bar']; var regex = /^([a-zA-Z0-9]{0,3})(?:([a-zA-Z]{1,2})([a-zA-Z0-9]+)?)?/; for (var i=0; i<texts.length;i++) { var serialCode = ''; var serialMarket = ''; var serialSuffixmatch = ''; var match = texts[i].match(regex); if (match) { serialCode = match[1]; serialMarket = (match[2] || ""); if (serialCode.length == 3 && serialMarket.length == 2) { serialSuffixmatch = match[3]; } } console.log(texts[i], '=>', serialCode + "\n" + serialMarket + "\n" + serialSuffixmatch); }

That is, simply use numbered capturing groups, and once a match is obtained, check the length of the first and second groups, and if the sum of their lengths is 5, grab Group 3 value, too.即简单地使用编号的捕获组,一旦得到匹配,检查第一组和第二组的长度,如果它们的长度之和为5,则也抓取Group 3的值。

You can use a conditional to start with your most restrictive pattern and work your way backwards to the least restrictive one:您可以使用条件从限制性最强的模式开始,然后向后工作到限制最少的模式:

^(?:[a-zA-Z0-9]{3}[a-zA-Z]{2}[a-zA-Z0-9]*|[a-zA-Z0-9]{3}[a-zA-Z]{1,2}|[a-zA-Z0-9]{0,3})

I don't know if the named capture groups have any significance for your JS code logic but unfortunately you cannot declare the same capture group name.我不知道命名的捕获组对您的 JS 代码逻辑是否有任何意义,但不幸的是您不能声明相同的捕获组名称。

https://regex101.com/r/2uztK5/1 https://regex101.com/r/2uztK5/1

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

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