我希望能够做一个正则表达式,我可以在其中识别出一组字母[dgos],例如在我的正则表达式中使用...但每当使用该字母时,它就会将其从银行中取出.
所以我们可以说,不知何故\1能够代表那一组字母(dgos).我可以写一个正则表达式:
^\1{1}o\1{2}$
Run Code Online (Sandbox Code Playgroud)
它基本匹配:
\1{1}= [dgos]{1}
o
\1{2}= [dgos]{2}减去第一个中使用的东西
匹配可以包括good,dosg,sogd等...和不包括sods(因为s必须使用两次)或sooo(因为o必须使用两次).
我还希望能够识别可以多次使用的字母.我自己开始写这篇文章,但后来意识到我甚至不知道从哪里开始,所以我也一直在搜索,并没有找到一种非常优雅的方式来做到这一点,或者一种方法来做到灵活足以使用最少的输入轻松生成正则表达式.
我在下面使用条件和多个正则表达式的组合解决方案(随意评论关于该答案的想法 - 也许这是我必须这样做的方式?),但我希望在可能的情况下使用单个正则表达式解决方案...如果可能的话,更优雅,更有效.
请注意,更高级别的优雅和单一正则表达式部分只是我的偏好,最重要的是它的工作原理和性能足够好.
我想不出一种方法可以在正则表达式中完全做到这一点,但我能够想出这个: http: //jsfiddle.net/T2TMd/2/
由于 jsfiddle 受到帖子大小的限制,我无法在那里制作更大的字典。请在此处查看使用 180k 单词词典的更好示例。
主功能:
/*
* filter = regex to filter/split potential matches
* bank = available letters
* groups = capture groups that use the bank
* dict = list of words to search through
*/
var matchFind = function(filter, bank, groups, dict) {
var matches = [];
for(var i=0; i < dict.length; i++) {
if(dict[i].match(filter)){
var fail = false;
var b = bank;
var arr = dict[i].split(filter);
//loop groups that use letter bank
for(var k=0; k<groups.length && !fail; k++) {
var grp = arr[groups[k]] || [];
//loop characters of that group
for(var j=0; j<grp.length && !fail; j++) {
var regex = new RegExp(b);
var currChar = grp.charAt(j);
if(currChar.match(regex)) {
//match found, remove from bank
b = b.replace(currChar,"");
} else {
fail = true;
}
}
}
if(!fail) {
matches.push(dict[i]);
}
}
}
return matches;
}
Run Code Online (Sandbox Code Playgroud)
用法:
$("#go").click( function() {
var f = new RegExp($("#filter").val());
var b = "["+$("#bank").val().replace(/[^A-Za-z]+/g,"").toUpperCase()+"]";
var g = $("#groups").val().replace(/[^0-9,]+/g,"").split(",") || [];
$("#result").text(matchFind(f,b,g,dict).toString());
});
Run Code Online (Sandbox Code Playgroud)
为了更容易创建场景,我也创建了这个:
$("#build").click( function() {
var bank = "["+$("#buildBank").val().replace(/[^A-Za-z]+/g,"").toUpperCase()+"]";
var buildArr = $("#builder").val().split(",");
var groups = [];
var build = "^";
for(var i=0; i<buildArr.length; i++) {
var part = buildArr[i];
if(/\</.test(part)) {
part = "(" + bank + part.replace("<", "{").replace(">", "}").replace("-",",") + ")";
build = build + part;
groups.push(i+1);
} else {
build = build + "("+part+")";
}
}
build = build + "$";
$("#filter").val(build);
$("#bank").val(bank);
$("#groups").val(groups.toString());
$("#go").click();
});
Run Code Online (Sandbox Code Playgroud)
这在拼字游戏中很有用,所以假设您处于一个单词必须以“D”开头的位置,在平行单词的“D”和“R”之间有两个空格,并且您OAEES有你的信库。在构建器中我可以放入D,<2>,R,<0-3>,因为它必须以 D 开头,然后必须有银行的 2 个字母,然后是 R,然后我最多可以使用 3 个字母(因为我在中间使用了 2 个字母) D 和 R)。
构建器将使用字母库并转换D,<2>,R,<0-3>为^(D)([OAEES]{2})(R)([OAEES]{0,5})$用于过滤可能的匹配项的字母库。然后,对于这些可能的匹配,它将逐个字符地查看使用字母库的捕获组,当找到这些字母时,从该正则表达式中删除字母,这样,如果使用的字母库字母多于其中的字母,则不会匹配是在信库里。
在这里测试上面的场景。