正则表达式负查找在JavaScript中无效
考虑:正则表达式负查找在JavaScript中无效,javascript,regex,regex-lookarounds,Javascript,Regex,Regex Lookarounds,考虑: var re = /(?<=foo)bar/gi; var re=/(?以下是一种在JS中使用DOM解析HTML字符串并仅在标记之外执行替换的方法: vars='552>=12>1'; var doc=document.createDocumentFragment(); var wrapper=document.createElement('myelt'); wrapper.innerHTML=s; 附加子文档(包装器); 函数textNodesUnder(el){ var n
var re = /(?<=foo)bar/gi;
var re=/(?以下是一种在JS中使用DOM解析HTML字符串并仅在标记之外执行替换的方法:
vars='552>=12>1';
var doc=document.createDocumentFragment();
var wrapper=document.createElement('myelt');
wrapper.innerHTML=s;
附加子文档(包装器);
函数textNodesUnder(el){
var n,walk=document.createTreeWalker(el,NodeFilter.SHOW_TEXT,null,false);
while(n=walk.nextNode())
{
if(n.parentNode.nodeName.toLowerCase()='myelt')
n、 nodeValue=n.nodeValue.replace(/>=?/g,“相等”);
}
返回el.firstChild.innerHTML;
}
var res=textNodesUnder(doc);
控制台日志(res);
警报(res);
2020更新:Javascript实现开始以本机方式支持。ECMAScript 2021的一份提案草案已在Chrome 62+(2017-10-17发布)中实施,并已通过Firefox 78+中的for IREGEXP获取(,发布于2020-06-30)。其他JS口译员将跟进
实现lookbehinds的遗留解决方案
JavaScript缺乏对like(?
匹配(非全局)
正向后视匹配:
“填充”当然可能包括填充数组以供进一步使用
全球消极落后:
这将获取目标字符串并用baz
替换bar
的实例,只要它们遵循foo
。如果它们遵循foo
,则匹配$1
,三元运算符()返回匹配的文本和替换文本(而不是bar
部分)。否则,三元运算符将返回原始文本
反向查找替换:
//假设您想要mystring.replace(/(?)?
这本质上是相同的,但由于它是一个负回溯,当$1
缺失时,它会起作用(我们不需要在这里说$1+“baz”
,因为我们知道$1
是空的)
这与另一个动态宽度负lookbehind解决方案具有相同的警告,并通过使用固定宽度方法进行了类似的修复。因为JS不支持lookbehinds。请使用var re=/foo(bar)/gi;
。真正的问题是什么?这是正lookbehind btw。这是负的。(?正如Wiktor所说,javascript不支持lookbehinds。我想在span中匹配>=和>,但不包括>。示例数据为55 2>=12>1。该文本来自何处?它是否在DOM中?谢谢。你能让演示在regex101中工作吗?
regex的演示吗?抱歉,我需要更复杂的测试案例。请看,众所周知,JS中的HTML应该使用DOM解析器进行处理,而regex应该只针对tex节点运行。请看。原始问题在别处列出了改进(对问题的注释和另一个答案)。我还回答了改进的版本(向下滚动到“您的特定用例”)在这个答案的旧版本中,但后来删除了它,以使答案更简洁,更适用于实际问题。关于全局匹配前瞻中的注释:为了避免干扰问题,使用(?转换为(ba)?ll
:一个简单的解决方法是只使用一个位置并使用一个前向:(ba)?(?=ll)。
关于固定宽度负后向查找匹配:模式(?!foo)(?:^.{0,2}}.{3})(bar)
最好这样写:(?:^.{0,2}.{124;(?!foo)。{3})(bar)
(此外,假设您必须以fooar
开头的字符串处理foo/oar,而不是foo/bar)。“PCRE、PHP和Perl仅限于固定宽度”:PHP使用PCRE正则表达式引擎。还请注意,固定宽度子模式的交替是可能的:(?@casimirithippolyte–是的,将鼠标悬停在PHP链接上,您会看到我提到它使用libpcre。您确实可以在固定宽度的lookbehind中使用替换,只要所有替换都具有相同的宽度,但替换中不同的宽度不会在所有引擎中都起作用。我没有审查您的其他评论,但在全局匹配可能存在迭代问题。
// from /(?<=foo)bar/i
var matcher = mystring.match( /foo(bar)/i );
if (matcher) {
// do stuff with matcher[1] which is the part that matches "bar"
}
// from /(?<!foo)bar/i
var matcher = mystring.match( /(?!foo)(?:^.{0,2}|.{3})(bar)/i );
if (matcher) {
// do stuff with matcher[1] ("bar"), which does not follow "foo"
}
var re = /foo(bar)/gi; // from /(?<=foo)bar/gi
while ( matcher = re.exec(mystring) ) {
// do stuff with matcher[1] which is the part that matches "bar"
}
var re = /(foo)?bar/gi; // from /(?<!foo)bar/gi
while ( matcher = re.exec(mystring) ) {
if (!matcher[1]) {
// do stuff with matcher[0] ("bar"), which does not follow "foo"
}
}
// assuming you wanted mystring.replace(/(?<=foo)bar/i, "baz"):
mystring = mystring.replace( /(foo)?bar/i,
function ($0, $1) { return ($1 ? $1 + "baz" : $0) }
);
// assuming you wanted mystring.replace(/(?<!foo)bar/i, "baz"):
mystring = mystring.replace( /(foo)?bar/i,
function ($0, $1) { return ($1 ? $0 : "baz") }
);