【问题标题】:How to make a regex for files ending in .php?如何为以 .php 结尾的文件制作正则表达式?
【发布时间】:2011-03-25 03:49:57
【问题描述】:

我正在尝试编写一个非常简单的正则表达式来匹配任何不以 .php 结尾的文件名。我想出了以下...

(.*?)(?!\.php)$

...但是这匹配所有文件名。如果有人能指出我正确的方向,我将不胜感激。

【问题讨论】:

  • 什么语言?每个都在它的 RegEx 实现上有所不同,所以知道这一点很重要 - php?珀尔? Python?爪哇? javascript? .net?
  • 正则表达式是用PHP写的吗?实现语言非常重要。
  • 您从来没有为人们发布的任何问题的答案投票,也没有接受其中任何一个。考虑这样做:这几乎就是 SO 的精神。
  • 巴特,我其实很清楚这一点,但坦率地说,我认为我之前的任何问题都没有得到有用的答复。回复其他绅士,该语言实际上是针对Apache(ProxyPasMatch)的。
  • 好的,很公平。尽管您的第一个问题(以及您对其中某个答案的评论)似乎与您的评论相矛盾。

标签: regex regex-negation regex-lookarounds


【解决方案1】:

你在字符串的末尾,正在向前看。您想要的是背后 看看:

(.*)$(?<!\.php)

请注意,并非所有正则表达式引擎都支持后向断言。

【讨论】:

  • 我知道您只是从 OP 的正则表达式中复制了它,但是那个不情愿的量词没有任何意义。当您知道只需要在末尾应用时,您正在强制正则表达式为字符串中的每个字符评估一次后向。事实上,我会把lookbehind 放在锚点之后:.*$(?&lt;!\.php)
  • @Alan Moore:是的,关于将前瞻放置在锚点之后的性能,您可能是对的。虽然我不确定在某些正则表达式引擎中,$ 锚是否会消耗一个尾随的换行符,这会产生不同的结果。不过,在 Apache 中解析 URL 时,这可能不会成为问题。
【解决方案2】:

有时在宿主语言级别使用正则表达式之外的否定而不是使用否定前瞻。在许多语言中,boolean 补码运算符是一元 !

所以你可以这样写:

! str.hasMatch(/\.php$/)

根据语言,您也可以完全跳过正则表达式并使用类似的东西(例如 Java):

! str.endsWith(".php")

至于原始模式本身的问题:

(.*?)(?!\.php)$   // original pattern, doesn't work!

这匹配,比如file.php,因为(.*?) 可以捕获file.php,并且向前看,你不能匹配\.php,但你可以匹配@987654333 @,所以完全是一场比赛!您可能想要使用look behind,或者如果它不受支持,您可以在字符串的start处进行lookahead。

^(?!.*\.php$).*$  // negative lookahead, works

这将匹配所有不以".php" 结尾的字符串,并使用负前瞻。

参考文献

相关问题

【讨论】:

  • 一个更具体的示例模式,分别捕获前缀部分和扩展部分。 rubular.com/r/xHizeFtbXb - 有很大的改进空间,但这需要更精确的规范。
  • 感谢 poly,我应该在我的 OP 中提到这是针对 Apache 代理的东西。通常我会在代码中进行否定,但显然在这种情况下我们没有选择。无论如何感谢您的回复。
【解决方案3】:

差不多:

.*(?!\.php)....$

最后四个点确保有可以向前看的东西,当检查前瞻时。

外括号是不必要的,因为您对整个匹配感兴趣。

不情愿的.*? 是不必要的,因为回溯四个步骤比每一步检查以下条件更有效。

【讨论】:

  • 非常感谢 Tomalak,它非常适合以后查看此内容的任何人,我们使用的最终代码是 ProxyPassMatch ^(.*)\.((?!php)...)* $127.0.0.1:12345/$1.$2
  • Minor pedant:这不会匹配文件名长度小于 4 个字符的文件。
  • ProxyPassMatch ^(.*\.(?!php).*)$ 127.0.0.1:12345/$1 - 是我们用于将来参考的最终版本,它还修复了文件名长度问题(经过测试文件名 i.php)
  • @Mark Byers:你说得对,我没有想到这个案子。正确的是^(.{1,3}|.*(?!\.php)....)$
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-22
  • 1970-01-01
  • 2020-05-07
  • 1970-01-01
  • 2016-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多