创建动态正则表达式以匹配不同字符集(运行时提供的字符及其顺序)的最佳方法是什么。
character set: abcd
character format: ??j? (question mark represents a a character from character set)
示例
abjd = match
bdja = match
dbja = match
ab = no match
aajd = no match
abjdd = no match
abj = no match
我创建了一个正则表达式构建器(在js中),如下所示:
// characters are the character set
// wordFormat is the character format
// replace(str, search, replacement) replaces search in str with replacement
var chars = "[" + characters + "]{1}";
var afterSpecialConversion = replace(wordFormat, "?", chars);
var myRegex = new RegExp("^" + afterSpecialConversion + "$", "gi");
不幸的是,由于不考虑重复项目,因此无法实现结果。我想过使用匹配组来避免重复,但是我不知道如何从集合的其余部分中否定已存在的字符组。
同样给定字符集aabcd
现在a
可以存在两次。有什么建议?
答案 0 :(得分:1)
你的正则表达式构建器方法是正确的(尽管有点可操作性,所以请仔细记录),但不够复杂。您需要做的是使用lookaheads。
我在您的问题中为演示提供了example regex on Regex101。
更一般的原则是用与此匹配的模式替换每组n
个问号:
(?:([<chars>])(?!.*\<m>)){<n>}
<chars>
是您要使用的字符集,m
是问号集的索引(从1开始 - 稍后会详细介绍)和{{1} }是组中的问号数。这会产生如下所示的正则表达式构建器代码:
<n>
显然,这个函数定义非常冗长,以证明所涉及的原则。随意打高尔夫球(但请记住注意我在评论中描述的fencepost问题。)
此外,请务必清理输入。这是一个示例,如果某人在function getRe(pattern, chars) {
var re = "^";
var qMarkGroup = 1;
var qMarkCount = 0;
for (var index in pattern) {
var char = pattern[index];
if (char === "?") {
qMarkCount += 1;
} else {
if (qMarkCount > 0) {
re += "(?:([" + chars + "])(?!.*\\" + qMarkGroup + ")){" + qMarkCount + "}" + char;
qMarkCount = 0;
qMarkGroup += 1;
}
}
}
// Need to do this again in case we have a group of question marks at the end of the pattern
if (qMarkCount > 0) {
re += "(?:([" + chars + "])(?!.*\\" + qMarkGroup + ")){" + qMarkCount + "}";
}
re += "$";
return new Regexp(re, "gi");
}
中放入]
,则会中断。