正则表达式负查找在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") }
);