Javascript 负前瞻正则表达式
我有这样一个字符串:Javascript 负前瞻正则表达式,javascript,regex,Javascript,Regex,我有这样一个字符串: <p>Year: ={year}</p>\ <p>Director: ={director}</p>\ <ul>@{actors}<li class="#{class}">={actor}</li>{actors}</ul>\ 有什么想法吗 编辑:我当前的解决方案是在@{}…{}中查找所有={match},并将=替换为类似=的内容。然后我抓取外面的,最后我回来,把带标记的放回原
<p>Year: ={year}</p>\
<p>Director: ={director}</p>\
<ul>@{actors}<li class="#{class}">={actor}</li>{actors}</ul>\
有什么想法吗
编辑:我当前的解决方案是在
@{}…{}
中查找所有={match}
,并将=
替换为类似=
的内容。然后我抓取外面的,最后我回来,把带标记的放回原来的状态。在这里,你需要负向展望结尾{whatever}
/(?!@.*)=\{([^{}]+)\}(?。*{[^{}]+\})/g
更新:
Previous仅适用于每行的{match}
挂接@
实际上意味着一个LookBehind,在这种情况下很难使用LookBehind,因为LookBehind非常想知道要查找多少个字符
因此,让我们使用LookAhead进行前瞻:=\{([^{}]+)\}(?![^@]*[^=@]{)
在末尾挂起{tag}
编辑:demo您可以使用正则表达式将字符串分解为段,如下所示:
var s = '<p>Year: ={year}</p> \
<p>Director: ={director}</p> \
<ul>@{actors}<li class="#{class}">={actor}</li>{actors}</ul>',
re = /@\{([^}]+)\}(.*?)\{\1\}/g,
start = 0,
segments = [];
while (match = re.exec(s)) {
if (match.index > start) {
segments.push([start, match.index - start, true]);
}
segments.push([match.index, re.lastIndex - match.index, false]);
start = re.lastIndex;
}
if (start < s.length) {
segments.push([start, s.length - start, true]);
}
console.log(segments);
布尔值指示您是在-true
-之外还是在@{}…{}
段内。它使用反向引用将结束与开始匹配
然后,基于段,您可以按照正常方式执行替换。这些
@{word}…{word}
构造是否可以嵌套?此外,在{code>之前似乎有一些“特殊字符”,如@
、=
和
将其与结束标记区分开来。这些都是我们需要考虑的,还是还有其他需要考虑的?如果您可以使用@{tag1}…={word}…@{tag2}…{tag2}…{tag1}
,那么你不能单独使用正则表达式。JavaScript正则表达式不支持任何类型的递归。@TimPietzcker:我对循环使用反向引用,/{([^{}]+)\}(.+)\{\1\}/
,因此{tag1}
将只匹配结束的{tag1}
在该匹配中,我可以再次运行同一个正则表达式…好的,一个文档既不能包含@{tag}…{tag}…{tag}
也不能包含@{tag}…{tag tag}…@{tag}…{tag}
?@elclanrs:但是嵌套对象中的键可能会出现在不同的级别上。我认为正则表达式并不是最好的工具,您是否尝试过一个简单的基于堆栈的解析器?这只适用于示例,因为={…}之间有一个换行符
tags。这个看起来不错,我要试试。@elclanrs-someas:)很高兴能帮上忙!
var s = '<p>Year: ={year}</p> \
<p>Director: ={director}</p> \
<ul>@{actors}<li class="#{class}">={actor}</li>{actors}</ul>',
re = /@\{([^}]+)\}(.*?)\{\1\}/g,
start = 0,
segments = [];
while (match = re.exec(s)) {
if (match.index > start) {
segments.push([start, match.index - start, true]);
}
segments.push([match.index, re.lastIndex - match.index, false]);
start = re.lastIndex;
}
if (start < s.length) {
segments.push([start, s.length - start, true]);
}
console.log(segments);
[
[0, 54, true],
[54, 51, false],
[105, 5, true]
]