Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 在文件名和扩展名之间插入数值的正则表达式_Regex_Caching_Coldfusion - Fatal编程技术网

Regex 在文件名和扩展名之间插入数值的正则表达式

Regex 在文件名和扩展名之间插入数值的正则表达式,regex,caching,coldfusion,Regex,Caching,Coldfusion,在我读到的一篇文章中,如果我们传递一个带有JavaScript和CSS文件的查询字符串,比如style.CSS?V=1,在某些情况下浏览器不会缓存这些文件 因此,我决定编写一个函数,它将采用类似/css/style.css的文件路径,并返回/css/style.234242.css,其中234242是unix时间戳 <cfset mtime = 2342342> <cfset fileName = "/css/style.css"> <cfset newFileN

在我读到的一篇文章中,如果我们传递一个带有JavaScript和CSS文件的查询字符串,比如
style.CSS?V=1
,在某些情况下浏览器不会缓存这些文件

因此,我决定编写一个函数,它将采用类似
/css/style.css
的文件路径,并返回
/css/style.234242.css
,其中234242是unix时间戳

<cfset mtime = 2342342>
<cfset fileName = "/css/style.css">

<cfset newFileName = REReplace(fileName,'{\\.([^./]+)$}',mtime)>
<cfdump var = "#newFileName#">

我从谷歌搜索中得到了这个
'{\\\.([^./]+)$}'
正则表达式,但它不起作用


我一点也不擅长正则表达式。请帮忙。

您使用正则表达式太复杂了。如前所述

有些人在遇到问题时会想:“我知道,我会用 正则表达式。“现在他们有两个问题。”

使用Coldfusion,您可以简单地将文件名视为一个列表,并使用
作为分隔符。您希望在该列表的最后一部分之前插入
mtime
值。假设您的文件名不包含多个
,您可以使用:

<cfset newFileName = listFirst(fileName, '.') & '.' & mtime & '.' & listLast(filename, '.')>

您找到的
{\\\.([^./]+)$}
不是一个正常运行的正则表达式-只要
{
}
没有像正则表达式那样使用。某些语言可能会将它们用作正则表达式的分隔符,但在实际正则表达式中,它们用于量词(例如
x{3,5}
x的5和3之间的匹配)

另外,使用
\.
查找文本
\
,后跟
作为元字符(这不是目的-它应该是
\.
)。(同样,这可能是由于该示例来自要求转义反斜杠的任何语言;CF不要求转义反斜杠,因此这样做会干扰正则表达式的行为。)

正则表达式解决方案: 这使用一个前瞻
(?=…
)而不是一个捕获组来简化替换侧-替换插入到最后
之前的位置,而不替换任何实际字符

如果要替换时间戳,可以很容易地将
\.\d+
添加到开始处,让它正常工作

非正则表达式解决方案: 可能更有效(但不一定达到显著水平)


regex的缺点之一是它们是单向的——它们从一开始就开始,然后继续前进。对于长字符串,如果只关心最后几个字符,则可能会浪费时间查看不关心的字符。像
lastIndexOf
ListLast
这样的方法从末尾向后工作,从而避免了那些不必要的检查。同样,在这种情况下,字符串足够短,这几乎肯定无关紧要,但值得记住。

这里有一个基于列表的解决方案,可能更简单一些,并且解决了Peter提到的一个文件名中不止一个

<cfset mtime = 2342342>
<cfset fileName = "/css/style.css">
<cfset newFileName = listInsertAt( fileName, listLen( filename, '.'), mtime, '.' ) />


您可能需要添加更多的逻辑来检查
listLen(filename,'.')
是否至少为2,但这只是一个开始。

+1表示好的解决方案和好的报价。。。顺便说一句,你知道吗?:)否决这一愚蠢的引语/神话,也是因为它依赖于包含单个
字符的文件。同意彼得的观点,对不起,邓克。还有:我喜欢正则表达式,但可能不是解决这个问题的最佳方法。我对这个解决方案做了一个小小的调整,这样它就可以适用于任何文件名(我认为只是与Peter的不同语法)。。。也许将其作为您自己的答案发布:-)顺便说一句,您的缓存问题很可能与随文件一起发送的标题有关-确保服务器正在发送适当的expires/cache control/last modified Header。@彼得伯顿:这就是为什么我要用类似style.23423324.css的文件名附加上次修改的时间戳,这样服务器可以在更改文件时自动重新加载该文件。更改文件名并不意味着不需要设置适当的HTTP头。您没有说明如何获取unix时间戳,但gettickcount()可能更简单。@DanBracuk:
很好的正则表达式,Peter!从来没有想过在这样的替换中使用前瞻。是的,记住regex在位置上起作用是很方便的-我在IDE端使用了很多(例如,跨文件重构),但令人恼火的是,它在Eclipse中不起作用,我必须切换到jEdit。(旁注:我并没有忽略你写的那篇McName文章,只是还没有足够的空闲时间来回复——希望是这个周末。)
Left(filename,filename.lastIndexOf('.')+1) & mtime & '.' & ListLast(filename,'.')
<cfset mtime = 2342342>
<cfset fileName = "/css/style.css">
<cfset newFileName = listInsertAt( fileName, listLen( filename, '.'), mtime, '.' ) />