我需要根据结构化的源字符串匹配多个行的多个组。
字符串的格式为每行一个名称,但是还有一些其他值,按此顺序:
我需要为每一行检索这4组。这就是我正在尝试的:
/^(\d+)?(?:[ \t]?[x:.=]?)[ \t]?(.+?)(?=[ \t]?(\(\w{3,4}\))?[ \t]?(\*))$/igm
要记住这个数字:
^(\d+)?
清理可能的分隔符:
(?:[ \t]?[x:.=]?)
过滤每组之间的空间:
[ \t]?
名称(以及其他名称):
(.+?(?=[ \t]?(\(\w{3,4}\))?[ \t]?(\*)?))
显然,问题在于最后一个问题。它一起捕捉(第2,3和4组)。正如您所看到的,我尝试将最后两个可选组作为积极前瞻,将它们与名称分开。
我做错了什么或者如何更好地实现结果呢?
修改
字符串示例:
2 John Smith
3 Messala Oliveira (NMN) *
Mary Pop *
Joshua Junior (pMHH)
我需要什么:
[ "2", "John Smith", "", "" ],
[ "3", "Messala Oliveira", "(NMN)", "*" ],
[ "", "Mary Pop", "", "*" ],
[ "", "Joshua Junior", "(pMHH)", "" ],
答案 0 :(得分:0)
您需要使用可选的非捕获组包装可能存在或不存在的捕获组:
/^(?:(\d+)[ \t]*)?(.*?)(?:[ \t](\(\w{3,4}\)))?(?:[ \t](\*))?$/igm
请参阅regex demo。
<强>详情:
^
- 字符串开头(?:(\d+)[ \t]*)?
- 可选的非捕获组匹配
(\d+)
- (第1组)1+位数[ \t]*
- 0 +空格或制表符(如果使用\s
,则为0 +空格)(.*?)
- 第2组尽可能少地捕获除了亚麻布符号以外的任何0 +字符(?:[ \t](\(\w{3,4}\)))?
- 可选的组匹配
[ \t]
- 空格或标签(\(\w{3,4}\))
- 第3组捕获(
,3或4个字的字符,)
(?:[ \t](\*))?
- 与空格或制表符匹配的另一个可选组,并将*
符号捕获到第4组。$
- 字符串结束。如果您单独测试字符串,[ \t]
可以替换为更简单的\s
:
var regex = /^(?:(\d+)\s*)?(.*?)(?:\s(\(\w{3,4}\)))?(?:\s(\*))?$/i;
var strs = ['2 John Smith','3 Messala Oliveira (NMN) *','Mary Pop *','Joshua Junior (pMHH)'];
for (var i=0; i<strs.length; i++) {
if ((m = regex.exec(strs[i])) !== null) {
var res = [];
if (m[1]) {
res.push(m[1]);
} else res.push("");
res.push(m[2]);
if (m[3]) {
res.push(m[3]);
} else res.push("");
if (m[4]) {
res.push(m[4]);
} else res.push("");
}
console.log(res);
}
&#13;