我需要从旧版界面解析信息。我们无法更新旧消息。我对正则表达式不是很精通,但是我设法写了一个能满足我期望的表达式。我只需要同行评审和反馈以确保它是干净的。
来自旧系统的消息返回的值类似于下面的示例。
%name0=value
%name1=value
%name2=value
Expression: /\%(.*)\=(.*)/g;
var strBody = body_text.toString();
var myRegexp = /\%(.*)\=(.*)/g;
var match = myRegexp.exec(strBody);
var objPair = {};
while (match != null) {
if (match[1]) {
objPair[match[1].toLowerCase()] = match[2];
}
match = myRegexp.exec(strBody);
}
此代码有效,我可以在名称/值的中间添加部分匹配项而不会造成任何破坏。我必须假定字符的任何组合都可能出现在“值”匹配中。这意味着它在消息中可能具有等号和百分号。
答案 0 :(得分:2)
您的表达式很好,用两个捕获组将其包装起来很容易获得所需的变量和值。
您可能不需要转义一些字符,它仍然可以工作。
如果需要,您可以使用this tool并测试/编辑/修改/更改表达式:
%(.+)=(.+)
由于您的数据结构合理,因此您也可以使用字符串分割来实现,并根据需要获得相同的期望输出。
此图显示了表达式的工作方式,您可以在此link中可视化其他表达式:
const regex = /%(.+)=(.+)/gm;
const str = `%name0=value
%name1=value
%name2=value`;
let m;
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log(`Found match, group ${groupIndex}: ${match}`);
});
}
此JavaScript代码段使用简单的100万次for
循环来显示该表达式的性能。
const repeat = 1000000;
const start = Date.now();
for (var i = repeat; i >= 0; i--) {
const string = '%name0=value';
const regex = /(%(.+)=(.+))/gm;
var match = string.replace(regex, "\nGroup #1: $1 \n Group #2: $2 \n Group #3: $3 \n");
}
const end = Date.now() - start;
console.log("YAAAY! \"" + match + "\" is a match ");
console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test. ");
答案 1 :(得分:2)
首先,请不要转义不需要转义的字符:%(.*)=(.*)
表达式的问题:值中的等号会破坏解析器。 %name0=val=ue
将导致name0=val
= ue
而不是name0
= val=ue
。
一个可能的解决方法是通过添加问号%(.*?)=(.*)
但这不是最佳选择,因为不需要回溯。通过使用否定的字符类,您可以做得更好:%([^=]*)=(.*)
最后,如果不允许使用空名称,则将第一个星号替换为加号:%([^=]+)=(.*)