当前位置:  开发笔记 > 编程语言 > 正文

Javascript:负面的lookbehind相当于?

如何解决《Javascript:负面的lookbehind相当于?》经验,为你挑选了6个好方法。

有没有办法在javascript正则表达式中实现相当于负面的lookbehind?我需要匹配一个不以特定字符集开头的字符串.

如果在字符串的开头找到匹配的部分,我似乎无法找到正确执行此操作的正则表达式.负面的看起来似乎是唯一的答案,但javascript没有.

编辑:这是我想要工作的正则表达式,但它没有:

(?

所以它会匹配'jim'或'm'中的'm',但不会匹配'jam'



1> JBE..:

由于Javascript支持负前瞻,一种方法是:

    反转输入字符串

    与反向正则表达式匹配

    反转并重新格式化比赛


// positive lookbehind
(?<=...)
// negative lookbehind
(?

例1:

关注@ andrew-ensley的问题:

const reverse = s => s.split('').reverse().join('');

const test = (stringToTests, reversedRegexp) => stringToTests
  .map(reverse)
  .forEach((s,i) => {
    const match = reversedRegexp.test(s);
    console.log(stringToTests[i], match, 'token:', match ? reverse(reversedRegexp.exec(s)[0]) : 'Ø');
  });

输出:

test(['jim', 'm', 'jam'], /m(?!([abcdefg]))/)

例2:

关注@neaumusic评论(匹配max-height但不是line-height,令牌是height):

jim true token: m
m true token: m
jam false token: Ø

输出:

test(['max-height', 'line-height'], /thgieh(?!(-enil))/)


这种方法的问题在于,当你有前瞻和后瞻时,它不起作用
你能否展示一个工作实例,说我想匹配`max-height`而不是`line-height`我只希望匹配为`height`

2> Kamil Szot..:

我们假设你想找到所有int没有前面的unsigned:

支持负面观察:

(?

不支持负面观察:

((?!unsigned ).{9}|^.{0,8})int

基本上,想法是抓住前面的n个字符并排除与负前瞻的匹配,但也匹配没有前n个字符的情况.(其中n是后视的长度).

所以有问题的正则表达式:

(?

会转化为:

((?!([abcdefg])).|^)m

您可能需要使用捕获组来查找您感兴趣的字符串的确切位置,或者您希望用其他内容替换特定部分.


这应该是正确的答案.请参阅:"所以它会匹配'jim'或'm'中的'm',但不匹配'jam'".replace(/(j(?!([abcdefg])).| ^)m/g, "$ 1 [MATCH]")`返回`"所以它匹配'ji [MATCH]'或'm'中的'm',但不匹配'jam'"`这很简单,它有效!

3> Okku..:

后向断言得到了接受入ECMAScript规范在2018年这已得到落实V8并没有与谷歌浏览V62标志运和Node.js的V6标志和V9的背后没有一个标志.因此,如果您正在开发仅限Chrome的环境(例如Electron)或Node,您可以立即开始使用lookbehinds!

积极的背后使用:

console.log(
  "$9.99  €8.47".match(/(?<=\$)\d+(\.\d*)?/) // Matches "9.99"
);


4> Jason S..:

Mijoja的策略适用于您的具体案例,但不是一般的:

js>newString = "Fall ball bill balll llama".replace(/(ba)?ll/g,
   function($0,$1){ return $1?$0:"[match]";});
Fa[match] ball bi[match] balll [match]ama

这是一个例子,其目标是匹配double-l,但不是如果它前面是"ba".注意单词"balll" - 真正的lookbehind应该抑制前2个,但匹配第2对.但是通过匹配前2个,然后将该匹配忽略为误报,正则表达式引擎从该匹配结束开始,并忽略误报内的任何字符.


啊,你是对的.然而,这比我以前更接近.我可以接受这个,直到有更好的东西出现(比如javascript实际上实现了lookbehinds).

5> Mijoja..:

使用

newString = string.replace(/([abcdefg])?m/, function($0,$1){ return $1?$0:'m';});


@bug.不做任何事情的演示是一种奇怪的演示.答案就是好像它只是复制和粘贴,而不了解它是如何工作的.因此缺乏相应的解释和未能证明任何事情已经匹配.
这没有做任何事:`newString`总是等于`string`.为什么这么多人投票?
这个概念是正确的,但是是的,它并没有很好地演示.尝试在JS控制台中运行它......""Jim Jam Momm m".replace(/([abcdefg])?m/g,function($ 0,$ 1){return $ 1?$ 0:'[match]';} );`.它应该返回`Ji [match] Jam Mo [match] [match] [match]`.但同时请注意,正如Jason在下面提到的,它可能会在某些边缘情况下失败.
@MikeM:SO的规则是,如果它回答“书面”问题,那是正确的。OP未指定用例

6> Klemen Slavi..:

您可以通过否定您的字符集来定义非捕获组:

(?:[^a-g])m

...将匹配任何这些字母前面的每个m NOT.


这是真的.一个角色类代表......一个角色!您的所有非捕获组正在执行的操作不是在替换上下文中使该值可用.你的表达并不是说"每个m之前都没有任何这些字母",它说的是"每个m*前面都有一个字符*不是那些字母中的任何一个"
对于也解决原始问题(字符串的开头)的答案,它还必须包含一个选项,因此得到的正则表达式将是`(?:[^ ag] | ^)m`.有关运行示例,请参阅https://regex101.com/r/jL1iW6/2.
我认为这场比赛实际上也涵盖了前面的角色.
推荐阅读
k78283381
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有