我在JavaScript中有一个数组,其索引类似于net.up, net.down, net, err, err.warn
我有一个字符串,我需要找到与字符串匹配的所有索引。匹配有一些特殊的规则,但是......
'net。*'将返回net.up, net.down
'err'只会返回err
这是非常严格的,即'net.u *'不会返回任何内容。
目前,我正在考虑按句点拆分字符串,并将每个细分与每个细分进行比较,但这似乎很幼稚。
根据要求,我的代码有效,但我觉得太天真,希望改进:
o = {"hey":0,"hey.a":1,"hey.b":1,"no":0};
srch = "hey.*".split(".");
for(i in o) {
match = true;
parts = i.split(".");
for(j=0;j<srch.length;j++) {
if (parts[j]=="*" || srch[j]=="*") continue;
if (parts[j] != srch[j]) {
match=false;
break; } }
if (match)
document.write("match: "+i+"<br>"); }
答案 0 :(得分:0)
我不认为按句点分割字符串是天真的。要确定匹配,您需要验证输入字符串的每个部分是否与模式的每个部分匹配。这似乎就是你想要做的。
一种可能的优化方法 - 如果性能出于某种原因超级关键 - 可能是为了避免使用split
分配数组,而是用indexOf
逐位遍历每个字符串(以查找下一个点)和substring
。但是,如果有的话,那些代码将会更加复杂,而且可能几乎没有更快。
答案 1 :(得分:0)
在检查你的编辑后,这就是我的建议,在正则表达式的帮助下,你可以创建你想要的任何模式,不需要创建自己的通配符系统;正则表达式是最终的通配符:
var obj = {"hey":0,"hey.a":1,"hey.b":1,"no":0};
var hey = Object.keys(obj).filter(function(key){
return /^hey\.?.*?$/.test(key);
});
console.log(hey); //=> ["hey", "hey.a", "hey.b"]
修改:如果你只想要一个通配符,你仍然可以使用正则表达式,如下所示:
function filterwild(obj, wild) {
wild = new RegExp('^'+ wild.replace(/\.(.+?)\*/,'\\.$1.*?') +'$');
return Object.keys(obj).filter(function(k){ return wild.test(k) });
}
console.log(filterwild(obj,'hey')); //=> ["hey"]
console.log(filterwild(obj,'hey.*')); //=> ["hey","hey.a","hey.b"]
console.log(filterwild(obj,'hey.a*')); //=> ["hey.a"]
wild
为您提供了/^hey\.a.*?$/
(最后一个例子)的正则表达式。不确定这是你需要的确切输出;您可以根据需要调整正则表达式。
以上是上述快速演示:http://jsbin.com/ahixeq/2/edit
答案 2 :(得分:0)
如果我已正确理解了问题和评论,那么也许你正在寻找类似的东西。
的javascript
var o = {
"hey": 0,
"hey.a": 1,
"hey.b": 1,
"no": 0
};
function filterWild(object, search) {
var length = search.length,
matches = [],
searchLength = Infinity,
length;
if (length > 2 && search.slice(-2) === ".*") {
search = search.split(".");
length = search.length ;
if (length > 2) {
search = search.slice(-1).join(".") + ".";
searchLength = search.length;
} else if (length === 2) {
search = search[0] + ".";
searchLength = search.length;
} else {
search = search[0];
}
}
for (i in o) {
if (o.hasOwnProperty(i) && i.slice(0, searchLength) === search) {
matches.push(i);
}
}
return matches;
}
console.log(filterWild(o, "hey"));
console.log(filterWild(o, "hey.*"));
console.log(filterWild(o, "hey.a*"));
输出
["hey"]
["hey.a", "hey.b"]
[]
上
以上是jsperf上述函数与正则表达式版本
可能的性能提升是使用switch
代替if..else
语句,可能还有其他语句。
它没有使用任何ECMA5代码,但确实需要ECMA3兼容性,因此它应该对浏览器友好。