ANT Style Pattern Matcher - Mach-II/Mach-II-Framework GitHub Wiki
Available in Mach-II 1.8+
The MachII.util.AntPathMatcher
(1.8) or MachII.util.matching.AntPathMatcher
(1.9+) is a new utility that was introduced back in Mach-II 1.8 that makes matches against a path with a pattern using ANT-style wildcards. These wildcards look like regular expressions however it they really denote directives. This utility is the major algorithm that drives the view-loader functionality (load views by conventions) that was introduced in Mach-II 1.8.
One of the more common uses for the utility is see if a file path matches a certain pattern. This is useful for loading files on convention. For example, we use the utility for the new pattern view-loader in Mach-II 1.8 which loads all views that match a certain pattern. By default, the pattern used for the view-loader is /views/**/*.cfm
which will match all .cfm
files (the *.cfm
part of the pattern) in the /views
directory (the /views/
part of the pattern) and any directory below that (the **/
part of the pattern and without this part the matched paths would be to .cfm
files that are in the /views/
directory only).
Pattern / Path Separator | Pattern Results |
---|---|
/views/products/**/*.cfm |
Matches: /views/products/index.cfm /views/products/SE10/index.cfm /views/products/SE10/details.cfm /views/products/ST80/index.cfm /views/products/ST80/details.cfm Does Not Match: /views/index.cfm /views/aboutUs/index.cfm /views/aboutUs/managementTeam.cfm |
/views/**/*.cfm |
Matches: /views/index.cfm /views/aboutUs/index.cfm /views/aboutUs/managementTeam.cfm /views/products/index.cfm /views/products/SE10/index.cfm /views/products/SE10/details.cfm /views/products/ST80/index.cfm /views/products/ST80/details.cfm Does Not Match: /views/index.htm /views/readme.txt |
/views/index??.cfm |
Matches: /views/index01.cfm /views/index02.cfm /views/indexAA.cfm Does Not Match: /views/index01.htm /views/index1.cfm /views/indexA.cfm /views/indexOther.cfm /views/anotherDir/index01.cfm (Remember that ? matches a single character, so the above example matches only files that start with "index", followed by two wildcard characters and then ".cfm".) |
It should be noted that this utility can be used for things other than file paths. Any path that uses path separator (such as .
dots in CFC paths) can be used. The utility uses /
as the path separator when matching patterns against a path, but this be changed by passing in an argument to the init
method of the utility. For example, you could use the utility to match URLs against a pattern.
The utility uses three different wildcards.
Wilcard | Description |
---|---|
* |
Matches zero or more characters. |
? |
Matches exactly one character. |
** |
Matches zero or more directories. |
This method initializes the path pattern matcher and optionally allows you to provide a different path separator (which defaults to /
if not passed).
This is how you would create an instance of the utility (1.8):
<!--- Using the default path separator --->
<cfset matcher = CreateObject("component", "MachII.util.AntPathMatcher").init() />
<!--- Setting with a path separator of '.' --->
<cfset matcher = CreateObject("component", "MachII.util.AntPathMatcher").init(".") />
This is how you would create an instance of the utility (1.9+):
<!--- Using the default path separator --->
<cfset matcher = CreateObject("component", "MachII.util.matcher.SimplePatternMatcher").init() />
This method checks if the passed path has a pattern in it by checking to see if the pattern has any *
's or ?
's in it and returns a boolean result.
Example code:
<cfoutput>
Is '/views/index.cfm' a pattern: #matcher.isPattern("/views/index.cfm")#</br>
Is '/views/*.cfm' a pattern: #matcher.isPattern("/views/*.cfm")#
</cfoutput>
Example output:
Is '/views/index.cfm' a pattern: false
Is '/views/*.cfm' a pattern: true
This method matches the passed path against the pattern according to the matching strategy.
Example code:
<cfoutput>
Does this match: #matcher.match("*bla*/**/bla/**", "XXXblaXXXX/testing/testing/bla/testing/testing")#<br/>
Does this match: #matcher.match("/bla*bla/test", "/blaXXXbl/test")#
</cfoutput>
Example output:
Does this match: true
Does this match: false
This method matches the given path against the corresponding part of the given pattern according to the matching strategy and determines whether the pattern at least matches as far as the given base path goes, assuming that a full path may then match as well.
Example code:
<cfoutput>
Does this match: #matcher.matchStart("test/t*.txt", "test")#<br/>
Does this match: #matcher.matchStart("test*", "tst")#
</cfoutput>
Example output:
Does this match: true
Does this match: false
This method uses a given a pattern and a full path, determine the pattern-mapped part (starting with the element the first wildcard is located in).
Example code:
<cfoutput>
#matcher.extractPathWithinPattern("/d?cs/*", "/docs/cvs/commit")#</br>
#matcher.extractPathWithinPattern("/docs/c?s/*.html", "/docs/cvs/commit.html")#
</cfoutput>
Example output:
docs/cvs/commit
cvs/commit.html