In an article I read if we pass a querystring with JavaScript and CSS files like style.css?V=1, in some cases the browser does not cache the files.

So I have decided to write function that will take the file path like /css/style.css and will return /css/style.2342342.css where 2342342 is the unix timestamp.

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

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

I got this '{\\.([^./]+)$}' regular expression from a Google search but it is not working.

I am not at all good at regular expressions. Please help.

有帮助吗?

解决方案

You're over-complicating things by using a regex. As jwz said

"Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems."

With Coldfusion, you can simply treat your filename as a list with a . for a delimiter. You want to insert your mtime value before the last part of that list. Assuming your filename doesn't include more than one . you could use:

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

其他提示

The {\\.([^./]+)$} you found is not a functioning regex - in so far as { and } are not used like that in regex. It's possible some language uses those as delimiters for a regex, but in actual regex they are used for quantifiers, (for example x{3,5} matches between 5 and 3 of x).

Also, with \\. that is looking for a literal \ followed by . as a metacharacter (which is not the intent - it should just be \.). (Again this may be due to whatever language that example came from requiring backslashes to be escaped; CF doesn't require it, and thus doing so interferes with the regex behaviour.)

Regex solution:

rereplace( filename , '(?=\.[^./]+$)' , '.' & mtime )

This uses a lookahead (?=..) instead of a capturing group to simplify the replacement side - the replacement is inserted at the position before the final . without replacing any actual characters.

If it ever comes to replacing the timestamp, it's easy to add \.\d+ to the start and have it just work.

Non-regex solution:

Left(filename,filename.lastIndexOf('.')+1) & mtime & '.' & ListLast(filename,'.')

Potentially more efficient (but not necessarily to a significant level).

One of the downsides of regex is that they're one-way - they start at the beginning and go forward. For long strings when you only care about the last few characters that can mean wasting time looking at characters you don't care about. Methods like lastIndexOf and ListLast work backwards from the end, and thus avoid those unnecessary inspections. Again, in this situations the strings are short enough it almost certainly wont matter, but it is something worth keeping in mind.

Here is a list-based solution that may be a bit simpler - and, addresses the point Peter mentions about more than one . in a file name.

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

You would likely need to add more logic to check that listLen( filename, '.') is at least 2, but this is a start.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top