我的目标是解析一个具有特定格式的字符串,以便从中生成一个javascript对象结构。
一个想法是使用带有函数作为参数的String.replace。 所以在功能中你可以得到比赛的所有部分。 我的测试/例子到现在为止:
字符串:
!Norm: DIN 7985;
M2: 2, 2, 2;
M3:3,3;
M10: 20,25;
!Norm: DIN 7985 TX;
M4: 4, 4 , 4;
我的测试代码:
console.clear();
var sTmp = "!Norm: DIN 7985;\n M2: 2, 2, 2;\n M3:3,3;\n M10: 20,25;\n !Norm: DIN 7985 TX;\n M2: 6, 10 , 16;";
//console.log(sTmp);
function replacer(match, p1, p2, p3, p4, offset, string){
//console.log("-");
console.log("match:", match);
console.log("p1:", p1);
console.log("p2:", p2);
console.log("p3:", p3);
console.log("p4:", p4);
console.log("offset:", offset);
console.log("string:", string);
return "#";
}
//(?=!Norm:\s?(.+);\s+)
sTmp.replace(/\s*!Norm:\s?(.+);\s+(M\d+:.*\s*;)/g, replacer);
(在萤火虫中测试) 控制台日志(shortend):
match: !Norm: DIN 7985; M2: 2, 2, 2;
p1: DIN 7985
p2: M2: 2, 2, 2;
p3: 0
p4: !Norm: DIN 7985; M2: 2, 2, 2; M3:3,3; M10: 20,25; ....
offset: undefined
string: undefined
match: !Norm: DIN 7985 TX; M4: 4, 4 , 4;
p1: DIN 7985 TX
p2: M4: 4, 4 , 4;
p3: 52
p4: !Norm: DIN 7985; M2: 2, 2, 2; M3:3,3; M10: 20,25; !Norm: DIN 7985 TX; M4: 4, 4 , 4;
....
所以我可以看到这个想法有效 - 它符合规范,我将信息放在一个子字符串中。
现在有M3:......零件。
那么是否有一个选项来指定(M\d+:.*\s*;)
部分与下一个匹配!Norm:而不是;在第一次出现?
我认为应该可以用一个先行或其他什么方式?
这个想法背后的目标是从字符串中生成这样的javascript对象:
oDataTmp = {
DIN 7985 : {
M2 : ["2", "2", "2"],
M3 : ["3", "3"],
M10 : ["20", "25"],
}
DIN 7985 TX : {
M4 : ["4", "4", "4"],
}
}
我知道您可以通过拆分执行此操作,然后逐行解析。 我喜欢完成这项大脑工作的挑战,并了解如何做到这一点: - )
答案 0 :(得分:2)
这是我的正则表达式:
\s*!\w+:\s*([^;]+);\s*((?:\s*[^:!]+:[^;]+;)+)
它有以下匹配组:
此正则表达式并不特别指望关键字NORM。所以它可能是其他任何东西。如果要捕获它,只需在第一个\ w +。
周围添加括号说明:
/ # start regex
\s* # match optional whitespace
!\w+: # match word between '!' and ':'
\s* # match optional whitespace
([^;]+); # capture group 1 - match all characters (without ';') up to the next ';'
\s* # match optional whitespace
( # start capture group 2
(?: # group (non-capture)
\s* # match optional whitespace
[^:!]+: # match all characters (without ':' and '!') up to the next ':'
[^;]+; # match all characters (without ';') up to the next ';'
)+ # group end; match this group 1 to n times
) # end capture group 2
/g # end regex; set g-Flag for global
答案 1 :(得分:1)
您需要更改两件事以将所有成员合并为一个捕获。首先.
与换行符不匹配(并且您无法在JavaScript中更改它)。但[\s\S]
确实如此。是的,使用否定前瞻,我们可以确保我们不消耗下一个!Norm
:
/\s*!Norm:\s?(.+);\s+((?:(?![!]Norm)[\s\S])*)/g
我已将文字!
包装在方括号中,以明确它是文字,并将其从!
设置为负前瞻语法的一部分。你可以省略方括号,这只是为了便于阅读。所以基本上这将填充最后一次捕获任意字符,只要它们不启动新的!Norm
。
然后你可以继续,并从最后一次捕获中读取单个属性和值。
说明:
/ # start regex
\s* # match optional whitespace
!Norm: # match '!Norm:'
\s? # match optional whitespace
(.+); # capture group 1 - match all characters (whitout '\n') up to the next ';'
\s+ # match 1..n whitespaces
( # start capture group 2
(?: # group (non-capture)
(?! # negative lookahead
[!]Norm # match '!Norm'
) # end negative lookahead
[\s\S] # match a white space or other than white space character
# this group match a single character as long as it dont start are new !Norm
)* # group end; match this group 0..n times
) # end capture group 2
/g # end regex; set g-Flag for global
答案 2 :(得分:0)
所以在这里我有一个完整的解决方案 使用的正则表达式来自两个答案的组合:
console.clear();
var sData = "!Norm: DIN 933;\n !Norm: DIN 7985;\n M2: 2, 2, 2;\n M3:3,3;\n M10: 20,25;\n !Norm: DIN 7985 TX;\n M2: 6, 10 , 16;";
console.log(sTmp);
var oData = {};
// Parse sData with help of Regex replace
sData.replace(/\s*!Norm:\s*([^;]+);\s*((?:(?![!]Norm)[\s\S])*)/g,
function replacer(match, sNorm, sScrews, offset, string) {
//console.log("match:", match);
//console.log("sNorm:", sNorm);
//console.log("sScrews:", sScrews);
//console.log("offset:", offset);
//console.log("string:", string);
var oScrews = {};
sScrews.replace(/\s*(M\d+):\s*([^;]+);\s*/g,
function(match, sScrewSize, sScrewList, offset, string) {
//console.log("match:", match);
//console.log("sScrewSize:", sScrewSize);
//console.log("sScrewList:", sScrewList);
//console.log("offset:", offset);
//console.log("string:", string);
oScrews[sScrewSize] = sScrewList.split(/[\s,]+/);
return "§";
});
oData[sNorm] = oScrews;
return "#";
});
console.log("oData: ");
console.dir(oData);
结果对象(在控制台中验证):
oData = {
DIN 7985 : {
M10 : ["20", "25"],
M2 : ["2", "2", "2"],
M3 : ["3", "3"],
}
DIN 7985 TX : {
M4 : ["4", "4", "4"],
}
DIN 933 : {}
};