(?<!filename)\.js$
这与.js匹配以.js结尾的字符串,但filename.js除外(
)
JavaScript没有后面的正则表达式。有没有人能拼凑出一个可达到相同结果并可以在javascript中工作的替代正则表达式?
这里有一些想法,但需要辅助函数。我希望使用正则表达式来实现它:
http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript
#1 楼
^(?!filename).+\.js
对我有效经过了以下测试:
test.js匹配
可以在正则表达式中找到此正则表达式的正确说明,以匹配不包含单词的字符串?
自JavaScript 1.5版开始提供向前看,并且受所有主要浏览器支持
已更新,以匹配filename2.js和2filename.js,但不匹配filename.js
(^(?!filename\.js$).).+\.js
评论
您链接到的那个问题谈论的是一个稍微不同的问题:匹配一个在任何地方都不包含目标词的字符串。这很简单:匹配一个不以目标词开头的字符串。
–艾伦·摩尔
2011年9月11日下午5:50
那真的很好,它只漏掉了诸如filename2.js或filenameddk.js之类的情况。这是没有比赛,但应该是比赛。
–丹尼尔
2011年9月11日7:18
@daniel您要求进行回溯,而不是提前回溯,您为什么接受此答案?
– hek2mgl
15年5月28日在8:56
给定的一个与a.js不匹配
–inetphantom
16-3-17在12:35
带有lookbehind的原始正则表达式与2filename.js不匹配,但此处给出的正则表达式匹配。更加合适的是^(?!。* filename \ .js $)。* \。js $。这意味着匹配* filename.js以外的任何* .js。
– weibeld
17年5月16日在5:16
#2 楼
编辑:从ECMAScript 2018起,本地支持向后断言(甚至无边界)。在以前的版本中,您可以执行以下操作:
^(?:(?!filename\.js$).)*\.js$
这将明确地执行lookbehind表达式的隐式操作:检查字符串中的每个字符,如果lookbehind表达式加上后的正则表达式不匹配,则仅允许该字符匹配。
^ # Start of string
(?: # Try to match the following:
(?! # First assert that we can't match the following:
filename\.js # filename.js
$ # and end-of-string
) # End of negative lookahead
. # Match any character
)* # Repeat as needed
\.js # Match .js
$ # End of string
另一种编辑:
我很难说(特别是因为这个答案已经被广泛接受),有一种容易得多的方法可以实现这个目标。无需检查每个字符的前瞻性:
^(?!.*filename\.js$).*\.js$
也可以正常工作:
^ # Start of string
(?! # Assert that we can't match the following:
.* # any string,
filename\.js # followed by filename.js
$ # and end-of-string
) # End of negative lookahead
.* # Match any string
\.js # Match .js
$ # End of string
评论
适用于许多情况,但前面没有字符,例如:filename.js(works-nomatch)filename2.js(works-match)blah.js(works-match)2filename.js(不起作用-nomatch) ---话虽这么说,但后面的限制具有直到现在我都没有意识到的相同限制...
–丹尼尔
2011-09-11 7:40
@daniel:嗯,您的正则表达式(带有后向)也与2filename.js不匹配。我的正则表达式在与示例正则表达式完全相同的情况下匹配。
–蒂姆·皮茨克(Tim Pietzcker)
2011年9月11日17:51
原谅我的天真,但这里的非俘虏团体有用吗?我一直都知道这仅在尝试收集回字符串替换中的引用时才有用。据我所知,这也将起作用^(?! filename \ .js $)。* \。js $
–我想要答案
17 Mar 28 '17 6:46
不完全是,该正则表达式仅在字符串的开头检查“ filename.js”。但是^(?!。* filename \ .js $)。* \。js $可以工作。尝试考虑可能仍然需要ncgroup的情况...
–蒂姆·皮茨克(Tim Pietzcker)
17年3月28日在6:53
这种方法可以概括为:而不是在X后面看,而是在X之前看每个字符?
– ar鼠
18年6月29日在7:27
#3 楼
假设您要查找所有不以int
开头的unsigned
:支持负向后看:
(?<!unsigned )int
不支持负向后向查找:
((?!unsigned ).{9}|^.{0,8})int
基本思想是获取n个前面的字符并排除否定的匹配,但也要匹配不包含n个字符的情况。 (其中n是向后看的长度)。
正则表达式中的正则表达式:
(?<!filename)\.js$
将转换为:
((?!filename).{8}|^.{0,7})\.js$
您可能需要与捕获组一起使用,才能找到您感兴趣的字符串的确切位置,或者您不想用其他东西替换特定部分。
评论
我刚刚将其转换为:(?<!barna)(?<!ene)(?<!en)(?<!erne)(?:sin |vår)e?(?:$ |(?!egen | egne) )到(?!barna)。(?! erne)。(?! ene)。(?! en)..(?:sin |vår)e?(?:$ |(?!egen | egne))其中满足我的需要只是将其作为另一个“现实世界”场景提供。见链接
–艾里克·伯克兰(Eirik Birkeland)
16 Mar 16 '16 at 13:23
我认为您的意思是:((?!unsigned)。{9} | ^。{0,8})
– Pansay
17-2-4在10:07
@pansay是的。谢谢。我只是纠正了我的回答。
–卡米尔·索特(Kamil Szot)
17年2月13日在20:32
感谢您提供更通用的答案,即使在文本中需要进行深度匹配的情况下,该答案也可以使用(在此处最初的^不切实际)!
–米洛斯·姆多维奇(Milos Mrdovic)
17年8月17日在9:28
#4 楼
如果可以向前看但可以向后看,则可以先反转字符串,然后再进行前瞻。当然,还需要做更多的工作。评论
这个答案确实可以使用一些改进。在我看来,这更像是一则评论。
– mickmackusa
18年4月26日在6:31
#5 楼
这是Tim Pietzcker答案的等效解决方案(另请参见相同答案的注释):^(?!.*filename\.js$).*\.js$
表示匹配
*.js
,但*filename.js
除外。要获得此解决方案,您可以检查负向后看排除了哪些模式,然后使用负向前瞻来完全排除这些模式。
#6 楼
下面是一个正面的JavaScript替代方法,它显示了如何捕获以“ Michael”作为姓氏的人的姓氏。1)给定此文本:
const exampleText = "Michael, how are you? - Cool, how is John Williamns and Michael Jordan? I don't know but Michael Johnson is fine. Michael do you still score points with LeBron James, Michael Green Miller and Michael Wood?";
获取姓迈克尔的姓氏的数组。
结果应该是:
["Jordan","Johnson","Green","Wood"]
2)解决方案:
function getMichaelLastName2(text) {
return text
.match(/(?:Michael )([A-Z][a-z]+)/g)
.map(person => person.slice(person.indexOf(' ')+1));
}
// or even
.map(person => person.slice(8)); // since we know the length of "Michael "
3)检查解决方案
console.log(JSON.stringify( getMichaelLastName(exampleText) ));
// ["Jordan","Johnson","Green","Wood"]
此处演示:http://codepen.io/PiotrBerebecki/pen/GjwRoo
您也可以通过运行以下代码段尝试一下。
const inputText = "Michael, how are you? - Cool, how is John Williamns and Michael Jordan? I don't know but Michael Johnson is fine. Michael do you still score points with LeBron James, Michael Green Miller and Michael Wood?";
function getMichaelLastName(text) {
return text
.match(/(?:Michael )([A-Z][a-z]+)/g)
.map(person => person.slice(8));
}
console.log(JSON.stringify( getMichaelLastName(inputText) ));
评论
如果只需要检查特定的文件名或文件名列表,为什么不只使用两次检查呢?检查它是否以.js结尾,然后检查是否与filename.js不匹配,反之亦然。更新:最新的公共Chrome版本(v62)开箱即用地包含了lookbehinds:D但请注意,lookbehinds仍处于提议阶段3:github.com/tc39/proposal-regexp-lookbehind。因此,可能需要一段时间才能到处都支持JavaScript。最好在生产中使用时要小心!
#更新:ES2018包括后置断言加上:-dotAll模式(s标志)-后置断言-命名捕获组-Unicode属性转义
只需将(?<= thingy)thingy用于正向后视,而(?<!thingy)thingy用于负向后视。现在它支持它们。
@ K._截至2018年2月,这还不是真的!!而且这将需要一些时间,因为浏览器和引擎必须实现该规范(草案中为最新版本)。