javascript - 匹配给定的正则表达式,除非给定的单词存在(lookahead 或lookbehind)

标签 javascript regex regex-lookarounds lookbehind

我正在使用 javascript 正则表达式来解析一系列 URL。我需要匹配 URL 中的数字(实际上更复杂,但我正在简化),但只想匹配给定单词不在 URL 中的数字。

也就是说,我想排除其中包含“changelogs”一词的行,因此会捕获“1047”、“1048”、“1245” ' 和 '1049' 来自以下列表;

http://www.opera.com/docs/changelogs/unified/1215/
http://www.whatever.com/docs/changelogs/anythingelse/anything/1215/
http://www.blabblah/security/advisory/1047
http://booger/security/advisory/1048/
ftp://msn.global.whatever/somethingelse/1245
whatever/it/doesnt/matter/could/be/anything/i/still/want/this/number/1049/

我知道我需要某种环顾四周、向前看、向后看的方式,但我正在淘汰。这是我尝试过的最后一种模式;

(?!changelogs)(\d+)

Here is the regex101 sandbox I'm using .

此外,唯一匹配的是实际数字,这一点很重要。我不希望有任何其他内容匹配


这是我的 .NET 代码的样子(注意“BulletinOrAdvisoryPattern”是有问题的正则表达式)...

Regex bulletinPattern = new Regex(@matchingDomain.Vendor.BulletinOrAdvisoryPattern, RegexOptions.IgnoreCase );
Match bulletinMatch = bulletinPattern.Match(referenceTitle);

                    if (bulletinMatch.Success)
                    {
                        //Found the bulletin ID in the NVD Reference Title 
                        return bulletinMatch.Value;
                    }

最佳答案

您需要的“丑陋”正则表达式是

(?<=http://www\.opera\.com\b(?!.*/changelogs(?:/|$))\S*)\d+

请参阅.NET regex demo

但是,您所需要的只是

var result = input.Contains("/changelogs/") ? "" : input.Trim('/').Split('/').LastOrDefault();

请参阅IDEONE C# demo :

var lst = new List<string>() {"http://w...content-available-to-author-only...a.com/docs/changelogs/unified/1215/",
    "http://w...content-available-to-author-only...a.com/docs/changelogs/anythingelse/anything/1215/",
    "http://w...content-available-to-author-only...a.com/security/advisory/1047",
    "http://w...content-available-to-author-only...a.com/security/advisory/1048/",
    "http://w...content-available-to-author-only...a.com/doesnt/matter/could/be/anything/1049/"};
lst.ForEach(m => Console.WriteLine(
        m.Contains("/changelogs/") ? "" : m.Trim('/').Split('/').LastOrDefault()
    ));

更新

您将语言从 C# 切换到 JavaScript,这极大地改变了情况,因为 JS 正则表达式引擎不支持lookbehind。

因此,您必须解决它,并且有一些方法可以模仿lookbehind,或者仅使用捕获机制。

如果您可以使用捕获,请尝试

/^(?!.*\/changelogs(?:\/|$)).*\/(\d+)/

请参阅regex demo

var re = /^(?!.*\/changelogs(?:\/|$)).*\/(\d+)/gmi; 
var str = 'http://www.opera.com/docs/changelogs/unified/1215/\nhttp://www.whatever.com/docs/changelogs/anythingelse/anything/1215/\nhttp://www.blabblah/security/advisory/1047\nhttp://booger/security/advisory/1048/\nftp://msn.global.whatever/somethingelse/1245\nwhatever/it/doesnt/matter/could/be/anything/i/still/want/this/number/1049/';
var res = [];
 
while ((m = re.exec(str)) !== null) {
  res.push(m[1]);
}
document.body.innerHTML = JSON.stringify(res, 0, 4);

或者,使用可选组(如果要替换):

var re = /(\/changelogs\/.*)?\/(\d+)/gi; 
var str = 'http://www.opera.com/docs/changelogs/unified/1215/\nhttp://www.whatever.com/docs/changelogs/anythingelse/anything/1215/\nhttp://www.blabblah/security/advisory/1047\nhttp://booger/security/advisory/1048/\nftp://msn.global.whatever/somethingelse/1245\nwhatever/it/doesnt/matter/could/be/anything/i/still/want/this/number/1049/';
var result = str.replace(re, function (m, g1, g2){
  return g1 ? m : "NEW_VAL";
});
document.body.innerHTML = result;

关于javascript - 匹配给定的正则表达式,除非给定的单词存在(lookahead 或lookbehind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36948409/

相关文章:

javascript - Javascript 的意外输出

javascript - jquery中查找xml字符串节点是否有子元素

javascript - 使用正则表达式匹配哈希值,但当它们是 url 的一部分时则不匹配

javascript - 构建正则表达式

r - 尽管使用不捕获命令,字符仍然被捕获和突出显示

regex - Sublime Text正则表达式仅在不转义时起作用

javascript - 无法更改 div 的背景图像

regex - 使用编号在 bash 中拆分长行

javascript - 正则表达式性能 : Alternation vs Trie

javascript - 有没有办法在运行时获取扩展的设置(在 package.json 中定义)?