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

Improvement to my horrible switch statement for regex matching

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

为了节省非常长的代码块,我将我的函数缩减为下面的框架,以便它显示对开关的关注。

我研究了使用 .map 的可能性 return 真假,但我也不确定如何最好地实现它。

关于执行此操作的最佳方法有什么意见或建议吗?

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);
  }

}

您可以将对象放在一个数组中并调用测试函数直到一个 returns 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
    }
}

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

您可以创建一个包含 regex/function 对的数组并遍历该数组:

_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;
    }
}