REMatchGroups() ColdFusion User Defined Function

<cffunction
	name="REMatchGroups"
	access="public"
	returntype="array"
	output="false"
	hint="Returns the captrued groups for each pattern match.">
 
	<!--- Define arguments. --->
	<cfargument
		name="Text"
		type="string"
		required="true"
		hint="The target text in which we are trying to match patterns."
		/>
 
	<cfargument
		name="Pattern"
		type="string"
		required="true"
		hint="The regular expression patterns that we are matching."
		/>
 
	<cfargument
		name="Scope"
		type="string"
		required="false"
		default="ALL"
		hint="The scope of pattern matching (valid is ONE or ALL)."
		/>
 
 
	<!--- Define the local scope. --->
	<cfset var LOCAL = StructNew() />
 
 
	<!--- Create an array to hold our matches. --->
	<cfset LOCAL.Results = ArrayNew( 1 ) />
 
 
	<!--- Create the compiled pattern object. --->
	<cfset LOCAL.Pattern = CreateObject(
		"java",
		"java.util.regex.Pattern"
		).Compile(
			JavaCast( "string", ARGUMENTS.Pattern )
			)
		/>
 
	<!---
		Create the matcher for our pattern based on
		the target text.
	--->
	<cfset LOCAL.Matcher = LOCAL.Pattern.Matcher(
		JavaCast( "string", ARGUMENTS.Text )
		) />
 
 
	<!---
		Keep looping over the pattern matcher until it can no
		longer find a match OR the searching scope is satisified.
	--->
	<cfloop condition="LOCAL.Matcher.Find()">
 
		<!--- Create a struct to hold our groups. --->
		<cfset LOCAL.Groups = StructNew() />
 
 
		<!---
			Loop over the captured groups to store each one
			of them individually.
		--->
		<cfloop
			index="LOCAL.GroupIndex"
			from="0"
			to="#LOCAL.Matcher.GroupCount()#"
			step="1">
 
			<!---
				Store the captured group. If this group was not
				captured, then the key will not be valid in the
				struct (which is fine).
			--->
			<cfset LOCAL.Groups[ LOCAL.GroupIndex ] = LOCAL.Matcher.Group(
				JavaCast( "int", LOCAL.GroupIndex )
				) />
 
		</cfloop>
 
 
		<!--- Add this group to our results. --->
		<cfset ArrayAppend( LOCAL.Results, LOCAL.Groups ) />
 
		<!---
			Check to see if our search scope has been
			satisified by the number of matches found.
		--->
		<cfif (ARGUMENTS.Scope EQ "ONE")>
 
			<!--- We found our one match, so break out. --->
			<cfbreak />
 
		</cfif>
 
	</cfloop>
 
 
	<!--- Return the results. --->
	<cfreturn LOCAL.Results />
</cffunction>

For Cut-and-Paste