javascript regex - 寻找替代方案?

IT技术 javascript regex
2021-01-19 04:25:57

这是一个在大多数正则表达式实现中都能正常工作的正则表达式:

(?<!filename)\.js$

这与 .js 匹配以 .js 结尾的字符串,filename.js 除外

Javascript 没有正则表达式后视。有没有人能够组合一个替代的正则表达式来实现相同的结果并在 javascript 中工作?

这里有一些想法,但需要辅助功能。我希望只用一个正则表达式来实现它:http : //blog.stevenlevithan.com/archives/mimic-lookbehind-javascript

6个回答

编辑:从 ECMAScript 2018 开始,本机支持后视断言(甚至无界)

在以前的版本中,您可以这样做:

^(?:(?!filename\.js$).)*\.js$

这明确地执行了后视表达式隐式执行的操作:如果后视表达式加上它之后的正则表达式不匹配,则检查字符串的每个字符,然后才允许该字符匹配。

^                 # 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
@daniel:嗯,你的正则表达式(带lookbehind)也不匹配2filename.js我的正则表达式在与您的示例正则表达式完全相同的情况下匹配。
2021-03-16 04:25:57
原谅我的天真,但这里的非捕获组有用吗?我一直都知道只有在尝试收集字符串中的替换引用时才有用。据我所知,这也将起作用 ^(?!filename\.js$).*\.js$
2021-03-17 04:25:57
这种方法可以概括为:不是往X后面看,而是向前看X之前的每个字符?
2021-03-23 04:25:57
不完全是,该正则表达式仅在字符串的开头检查“filename.js”。^(?!.*filename\.js$).*\.js$会工作。试图考虑可能仍然需要 ncgroup 的情况......
2021-03-24 04:25:57
适用于许多情况,除了前面的字符,例如: filename.js (works-nomatch) filename2.js (works-match) blah.js (works - match) 2filename.js (doesn't work - nomatch) --- 话虽如此,后视具有相同的限制,我直到现在才意识到...
2021-04-08 04:25:57

^(?!filename).+\.js 为我工作

测试针对:

  • test.js 匹配
  • blabla.js 匹配
  • 文件名.js 不匹配

可以在正则表达式匹配不包含单词的字符串中找到此正则表达式的正确解释

javascript 版本 1.5起就可以使用前瞻功能,并且所有主要浏览器都支持

更新以匹配 filename2.js 和 2filename.js 但不匹配 filename.js

(^(?!filename\.js$).).+\.js

您链接到的那个问题讨论了一个略有不同的问题:匹配不包含目标词的字符串任何地方这个要简单得多:匹配一个不目标词开头的字符串
2021-03-18 04:25:57
带有lookbehind 的原始正则表达式不匹配2filename.js,但此处给出的正则表达式匹配一个更合适的将是^(?!.*filename\.js$).*\.js$这意味着,匹配任何*.js 除了 *filename.js
2021-03-20 04:25:57
给定的不匹配 a.js
2021-03-21 04:25:57
太好了,它只会遗漏以下情况:filename2.js 或 filenameddk.js 或类似情况。这不是一场比赛,但应该是一场比赛。
2021-04-05 04:25:57
@daniel 您要求的是回顾,而不是展望,您为什么接受这个答案?
2021-04-08 04:25:57

假设您想查找所有int不以 开头的内容unsigned

支持负向后视:

(?<!unsigned )int

不支持负向后视:

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

基本上的想法是抓取 n 个前面的字符并排除带有否定前瞻的匹配,但也匹配没有前面 n 个字符的情况。(其中 n 是后视的长度)。

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

(?<!filename)\.js$

会翻译成:

((?!filename).{8}|^.{0,7})\.js$

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

我想你的意思是: ((?!unsigned ).{9}|^.{0,8})int
2021-03-21 04:25:57
感谢您提供更通用的答案,即使需要在文本深处进行匹配(初始 ^ 是不切实际的)!
2021-04-05 04:25:57
我只是转换了这个:(?<!barna)(?<!ene)(?<!en)(?<!erne) (?:sin|vår)e?(?:$| (?!egen|egne))to (?!barna).(?!erne).(?!ene).(?!en).. (?:sin|vår)e?(?:$| (?!egen|egne))which 可以满足我的需要。只是将其作为另一个“真实世界”场景提供。链接
2021-04-08 04:25:57
@pansay 是的。谢谢你。我只是更正了我的回答。
2021-04-10 04:25:57

如果您可以向前看但可以向后看,您可以先反转字符串,然后再向前看。当然,还需要做一些工作。

这个答案真的可以使用一些改进。对我来说,这更像是评论。
2021-04-10 04:25:57

这是Tim Pietzcker 答案的等效解决方案(另请参阅相同答案的评论):

^(?!.*filename\.js$).*\.js$

这意味着,匹配*.js除了*filename.js

要获得此解决方案,您可以检查负向后视排除了哪些模式,然后使用负向后视准确排除这些模式。