I was standing in the deli this morning, checking out the girl next to me, when suddenly it occurred to me: ColdFusion custom tag list! How come there are no list functions that use regular expressions. That sounds confusing, let me explain. ColdFusion has this function, GetBaseTagList(). This will return a list of all parent tags that are open at the point of the GetBaseTagList() function call. To demonstrate:
Launch code in new window » Download code as text file »
Notice that the GetBaseTagList() is wrapped inside of a ColdFusion CFOutput tag, a CFSaveContent tag, a ColdFusion custom tag (, and then another CFOutput not shown). At this point, the GetBaseTagList() gives us this output:
CFOUTPUT,CFSAVECONTENT,CF_CUSTOMTAG,CFOUTPUT
Notice that the third tag, our ColdFusion custom tag, has a different naming convention; its name comes back with "CF_". All ColdFusion custom tags work that way. That's when it occurred to me - why not have a ListFind() function that uses a regular expression rather than a literal match?!? That way, we could find the index of the first custom tag without having to know what the tag name actually was.
But why stop there? Why not also make the delimiter a potential regular expression? And of course, since our item match is not a literal match, why not give people the option to return both the index AND the matched item? This will be like some super awesome combination of REFind(), ListFind() and ColdFusion 8's REMatch():
Launch code in new window » Download code as text file »
The first three arguments, List, RegEx, and Delimiter are just like the standard ListFind() arguments (except for our "item" is a regular expression, not a literal match). The last two arguments, neither of which are required, give us some cool functionality. RegExDelimiter allows us to flag the use of a regular expression as the delimiter rather than the standard character set. ReturnItem allows us to flag the return of a structure containing both the position of the match and the matched item itself, rather than just the index.
Let's give it a test. Using the ColdFusion base tag list from above, let's get the index of the first ColdFusion custom tag as denoted by any item that starts with "cf_":
Launch code in new window » Download code as text file »
This gives us the following output:
3
This, of course, is absolutely correct. CF_CUSTOMTAG is the third element in the list. Notice that our regular expression starts with a (?i). This is the case-INsensitive regular expression flag. Using this methodology stops me from having to create a redundant REListFindNoCase() tag. I am OK with because I feel that anyone using this kind of Find will probably also be comfortable using a case-insensitive expression.
Ok, but 3 doesn't really help us too much if we are trying to figure out what the closest ColdFusion custom tag is. So now, let's run the same thing, but this time, let's get back both the index and the matched item. To do this, we can use either ordered arguments with ALL the arguments, or named arguments, only passing in the ones we need. I chose named arguments cause it's smaller:
Launch code in new window » Download code as text file »
Running this, we get the following CFDump output:
| | | | ||
| | ![]() | | ||
| | | |
Now, we get both the position of the match, 3, and the item that was matched, CF_CUSTOMTAG. Very Cool!
But wait, there's more! The function, REListFind(), also gives us the ability to use a regular expression delimiter. This is not as awesome as the stuff above, but I thought I would throw it in there. Let's take a quick look at how this can be used:
Launch code in new window » Download code as text file »
Running this, we get the following CFDump output:
| | | | ||
| | ![]() | | ||
| | | |
Notice that here, we are using [\r\n\t]+ as are delimiter. Of course, we could have done this with a standard delimiter of "#Chr( 13 )##Chr( 10 )##Chr( 9 )#", but come on! That looks no good! The regular expression delimiter gives us some cool flexibility, I just didn't provide the best example.
Download Code Snippet ZIP File
Comments (4) | Post Comment | Ask Ben | Permalink | Other Searches | Print Page
Submit to CFLib.org please.
(I like that phrase - its like Submit to Zod please, or die)
Posted by Raymond Camden on Aug 1, 2007 at 11:01 AM
OK cool - this might have to be the first UDF I submit :) I have gone to submit before, and each time, it talks about cleaning up the file and stuff and I always have to scrap it (cause i am work billing clients ;))... but, at lunch, I might just go ahead and do this :)
Posted by Ben Nadel on Aug 1, 2007 at 11:26 AM
Nice work! This will be useful. Good to know that (?i) means case insensitive. It does make me wonder why I can't just use "/i" though (like most other languages) and while on that point, why not stick to the regex syntax of /blah/i.
Anyway, unrelated thought, how the heck do you go from checking out the girl next to you to custom tags list?! Was the girl wearing a CF shirt or something.
Posted by Boyan on Aug 1, 2007 at 1:29 PM
@Boyan,
I have learned not to question the way my brain works. My roommate in college use to give the "Non sequitur" of the day award all the time, cause the connections I make in my head follow no rational pattern at times :)
As far as the whole /regex/ syntax, I know Javascript can do that, but it always confuses me. I see that first "/" and it's like my brain just shuts down. Can't seem to read past it. That's why I always have to use new RegExp() in Javascript.
Posted by Ben Nadel on Aug 1, 2007 at 1:35 PM