Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 针对正则表达式匹配对我的可怕switch语句的改进_Javascript_Regex_Node.js_Switch Statement - Fatal编程技术网

Javascript 针对正则表达式匹配对我的可怕switch语句的改进

Javascript 针对正则表达式匹配对我的可怕switch语句的改进,javascript,regex,node.js,switch-statement,Javascript,Regex,Node.js,Switch Statement,我试图避免在node.js中使用可怕的切换案例。我正在寻找一种更有效的方法来针对各种正则表达式案例测试输入。根据匹配的情况,我要么触发一个事件,要么在运行另一个函数之前对输入进行一些转换 为了节省一个很长的代码块,我将我的函数缩减到下面的框架中,这样它就显示了对开关的关注 我已经研究了使用.map返回true-false的可能性,但我不确定如何最好地实现它 关于最好的方法有什么建议吗 function ParseLogMessages(message, config, callback){ va

我试图避免在node.js中使用可怕的切换案例。我正在寻找一种更有效的方法来针对各种正则表达式案例测试输入。根据匹配的情况,我要么触发一个事件,要么在运行另一个函数之前对输入进行一些转换

为了节省一个很长的代码块,我将我的函数缩减到下面的框架中,这样它就显示了对开关的关注

我已经研究了使用.map返回true-false的可能性,但我不确定如何最好地实现它

关于最好的方法有什么建议吗

function ParseLogMessages(message, config, callback){
var _this = this;

try {
//Define regex in order to match strings based on case
_this.to_group = new RegExp("^\\[\\d{2}:\\d{2}\\]\\s+\\w+\\s+tg+\\s\\>{3}");
_this.from_group=new RegExp("^\\[\\d\\d:\\d\\d\\]\\s\\w+\\s\\w+\\s\\>{3}");
_this.to_person = new RegExp("^\\[\\d{2}:\\d{2}\\]\\s[a-zA-Z0-9 \\- _]+\\s\\<{3}.+");
_this.from_person = new RegExp("^\\[\\d{2}:\\d{2}\\]\\s\\w+\\s\\>{3}");
_this.contact = new RegExp("(User #+\\d+:)");


_this.contact = new RegExp("(User #+\\d+:)");

//Test message against each to find type
switch (true){
    //Message sent to a group chat
    case _this.to_group.test(_this.payload.raw):
    break;

    //Message from a group chat
    case _this.from_group.test(_this.payload.raw):
    break;

    //Message sent to a person from the bot
    case _this.to_person.test(_this.payload.raw):
    break;

    //Message sent from a person to the bot
    case _this.from_person.test(_this.payload.raw):         
    break;

    //Contact shared
    case _this.contact.test(_this.payload.raw):     
    break;

    default:
    break;


}

callback(null,"Logfile message parsed ok!");

  } catch(err) {
    log.error(err);
    return callback(err,null);
  }

}
函数ParseLogMessages(消息、配置、回调){
var_this=这个;
试一试{
//定义正则表达式以便根据大小写匹配字符串
_this.to_group=new RegExp(“^\\[\\d{2}:\\d{2}\\\]\\s+\\w+\\s+tg+\\s\\>{3}”);
_this.from_group=new RegExp(“^\\[\\d\\d:\\d\\d\\\]\\s\\w+\\s\\w+\\s\\>{3}”);
_this.to_person=new RegExp(“^\\\[\\d{2}:\\d{2}\\\\]\\s[a-zA-Z0-9\\-\\\+\\s\\\\{3}”);
_this.contact=newregexp(“(用户#+\\d+:”)”;
_this.contact=newregexp(“(用户#+\\d+:”)”;
//针对每种类型测试消息以查找类型
开关(真){
//发送到群聊的消息
案例_this.to _group.test(_this.payload.raw):
打破
//来自群聊的消息
案例_this.来自_group.test(_this.payload.raw):
打破
//从bot发送给某人的消息
案例_this.to _person.test(_this.payload.raw):
打破
//从某人发送到bot的消息
案例_this.from_person.test(_this.payload.raw):
打破
//联系人共享
案例_this.contact.test(_this.payload.raw):
打破
违约:
打破
}
回调(null,“日志文件消息解析正常!”);
}捕捉(错误){
日志错误(err);
返回回调(err,null);
}
}

您可以将对象放入数组并调用测试函数,直到其中一个返回true:

var o = [
  _this.to_group,
  _this.from_group,
  _this.to_person,
  _this.from_person,
  _this.contact
];
for (var i in o) {
  if (o[i].test(_this.payload.raw)) {
    // got a match
    break;
  }
}

您需要将其转换为关联数组并与循环匹配。应能工作的未测试代码:

let patterns = {
    "^\\[\\d{2}:\\d{2}\\]\\s+\\w+\\s+tg+\\s\\>{3}": funcToGroup /* code for this case, preferably a [reference to a] function object without the parens */,
    "^\\[\\d\\d:\\d\\d\\]\\s\\w+\\s\\w+\\s\\>{3}": function () {
        // An inline anonymous function is also fine
    },
    "^\\[\\d{2}:\\d{2}\\]\\s[a-zA-Z0-9 \\- _]+\\s\\<{3}.+": funcToPerson,
    "^\\[\\d{2}:\\d{2}\\]\\s\\w+\\s\\>{3}": funcFromPerson,
    "(User #+\\d+:)": funcContactShared
};

for (let pat in _this.patterns) {
    if (new RegExp(pat).test(_this.payload.raw)) {
        _this.patterns[pat]();  // Actually execute the relevant case
    }
}
let模式={
“^\\\[\\d{2}:\\d{2}\\\\]\\s+\\w+\\s+tg+\\s\\>{3}”:funcToGroup/*代码对于这种情况,最好是一个不带parens*/.的[reference to a]函数对象,
“^\\[\\d\\d:\\d\\d\\]\\s\\w+\\s\\w+\\s\\>{3}”:函数(){
//内联匿名函数也可以
},
“^\\[\\d{2}:\\d{2}\\\]\\s[a-zA-Z0-9\\-\\\+\\s\\{3}”:funcFromPerson,
“(用户#+\\d+:)”:funcContactShared
};
为了(让帕特加入这个模式){
if(新的RegExp(pat).test(_this.payload.raw)){
_this.patterns[pat]();//实际执行相关案例
}
}

它应该处理
try
块中的所有代码。

您可以创建一个正则表达式/函数对数组,并在数组中循环:

_this.tests = [
    { regex: new RegExp("^\\[\\d{2}:\\d{2}\\]\\s+\\w+\\s+tg+\\s\\>{3}"), // to_group
      action: ... // action for to_group
    },
    { regex : new RegExp("^\\[\\d\\d:\\d\\d\\]\\s\\w+\\s\\w+\\s\\>{3}"), // from_group
      action: ... // action for from_group
    },
    // etc.
];
然后,在测试工作时,您可以在阵列中循环、测试和中断:

for (i=0; i<tests.length; ++i) {
    if (tests[i].regex.test(_this.payload.raw) {
        tests[i].action();
        break;
    }
}

用于(i=0;我的开关有问题,替代方法可能是一堆
if
语句?我把它作为标题,我会使用一个更真实的解析器。@adeneo它仍然可以比开关整洁得多,正如我的回答所希望显示的那样。@Nathantugy-不确定是否使用
let使用正则表达式作为函数键来做一些奇怪的事情等更整洁,没有assoc数组,只有对象。使用循环可以缩短代码,但它基本上做相同的事情,而且不太容易阅读,它只是缩短了代码?@adeneo:objects是JS关于assoc数组的想法;你知道,并不是所有的AAs都是以相同的方式实现的。至于其他的,连接“模式”使用{code}从定义上看,尽可能接近似乎是整齐的;你能问的唯一问题是你自己和同事是否足够理解。不确定你说的
是什么意思,但写一个答案吧?我很高兴看到我们独立地有了相同的想法!这是我本应该回答的,但我没有时间写出答案代码示例:)@NathanTuggy-是的,我们有非常相似的答案。但是,在
中使用“
for..in”将导致通过正则表达式的不可预测的迭代顺序。如果测试顺序很重要(我看不到假设最多一个正则表达式与有效负载数据匹配的依据),则应使用数组并按索引遍历。@TedHopp我的正则表达式实例确实取决于您建议的特定执行顺序。感谢您了解这一点。