Safari 的正则表达式后视替代方案
Regex lookbehind alternative for Safari
我已经实现了这个正则表达式来匹配字符串以进行验证:
^(?<serialCode>[a-zA-Z0-9]{0,3})(?:(?<serialMarket>[a-zA-Z]{1,2})(?<serialSuffix>(?<=^.{5})[a-zA-Z0-9]*)?)?
我在 JS 中使用它,使用 match()
函数,如下所示:
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
这基本上是做以下逐步验证和创建组:
- 前 3 个字符只能是字母数字字符
- 字符 4 和 5 只能是字母
- 其余所有字符应为字母数字字符
此验证针对输入字段中的每个键入值进行,一个字符一个字符。
如上所示,使用后视,这非常适合我在 Chrome 和 Mozilla Firefox 浏览器中的目的。
问题:lookbehind
(在当前情况下 (?<=^.{5})
)在 Safari 浏览器上不受支持 link:https://caniuse.com/js-regexp-lookbehind 在这种情况下我们收到此错误:Invalid regular expression: invalid group specifier name
是否有其他替代方案可以让正则表达式以完全相同的方式工作?
我有 link,我在其中测试了一些示例值:https://regex101.com/r/fPmiTk/1
在那里您可以看到字符串是如何匹配的以及组是如何创建的。
我怀疑是否有一种方法可以使用不支持回溯或条件的单个正则表达式,因此我建议采用以下结合正则表达式和其他编程逻辑的方法:
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);
}
也就是简单的使用编号的捕获组,一旦匹配到,检查第一组和第二组的长度,如果它们的长度之和为5,也抓取第三组的值。
您可以使用条件从限制性最强的模式开始,然后逐步退回到限制性最小的模式:
^(?:[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})
我不知道命名的捕获组对你的 JS 代码逻辑是否有任何意义,但不幸的是你不能声明相同的捕获组名称。
我已经实现了这个正则表达式来匹配字符串以进行验证:
^(?<serialCode>[a-zA-Z0-9]{0,3})(?:(?<serialMarket>[a-zA-Z]{1,2})(?<serialSuffix>(?<=^.{5})[a-zA-Z0-9]*)?)?
我在 JS 中使用它,使用 match()
函数,如下所示:
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
这基本上是做以下逐步验证和创建组:
- 前 3 个字符只能是字母数字字符
- 字符 4 和 5 只能是字母
- 其余所有字符应为字母数字字符
此验证针对输入字段中的每个键入值进行,一个字符一个字符。
如上所示,使用后视,这非常适合我在 Chrome 和 Mozilla Firefox 浏览器中的目的。
问题:lookbehind
(在当前情况下 (?<=^.{5})
)在 Safari 浏览器上不受支持 link:https://caniuse.com/js-regexp-lookbehind 在这种情况下我们收到此错误:Invalid regular expression: invalid group specifier name
是否有其他替代方案可以让正则表达式以完全相同的方式工作?
我有 link,我在其中测试了一些示例值:https://regex101.com/r/fPmiTk/1 在那里您可以看到字符串是如何匹配的以及组是如何创建的。
我怀疑是否有一种方法可以使用不支持回溯或条件的单个正则表达式,因此我建议采用以下结合正则表达式和其他编程逻辑的方法:
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);
}
也就是简单的使用编号的捕获组,一旦匹配到,检查第一组和第二组的长度,如果它们的长度之和为5,也抓取第三组的值。
您可以使用条件从限制性最强的模式开始,然后逐步退回到限制性最小的模式:
^(?:[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})
我不知道命名的捕获组对你的 JS 代码逻辑是否有任何意义,但不幸的是你不能声明相同的捕获组名称。