<cfcomponent
displayname="StringTokenzier"
output="false"
hint="Iterates over the tokens of a given string based on string delimiters and token qualifiers.">
<cfscript>
VARIABLES.Instance = StructNew();
VARIABLES.Instance.OriginalString = "";
VARIABLES.Instance.Delimiter = ",";
VARIABLES.Instance.Qualifier = "";
VARIABLES.Instance.TokenIndex = 0;
VARIABLES.Instance.RawTokens = "";
VARIABLES.Instance.RawTokenIndex = 0;
</cfscript>
<cffunction
name="Init"
access="public"
returntype="any"
output="false"
hint="Returns an initialized String Tokenizer instance.">
<cfargument
name="String"
type="string"
required="true"
hint="This is the string that will be broken up into tokens."
/>
<cfargument
name="Delimiter"
type="string"
required="false"
default=","
hint="This is the delimiter that will separate the tokens."
/>
<cfargument
name="Qualifier"
type="string"
required="false"
default=""""
hint="This is the qualifier that will wrap around fields that have special characters embeded."
/>
<cfset VARIABLES.Instance.Delimiter = Left( ARGUMENTS.Delimiter, 1 ) />
<cfif Len( ARGUMENTS.Qualifier )>
<cfset VARIABLES.Instance.Qualifier = Left( ARGUMENTS.Qualifier, 1 ) />
<cfelse>
<cfset VARIABLES.Instance.Qualifier = "" />
</cfif>
<cfset VARIABLES.Instance.OriginalString = ARGUMENTS.String />
<cfset VARIABLES.Instance.RawTokens = ToString(
" " &
ARGUMENTS.String
).ReplaceAll(
"([\#VARIABLES.Instance.Delimiter#]{1})",
"$1 "
).Split( "[\#VARIABLES.Instance.Delimiter#]{1}" )
/>
<cfset VARIABLES.Instance.TokenIndex = 0 />
<cfset VARIABLES.Instance.RawTokenIndex = 0 />
<cfreturn THIS />
</cffunction>
<cffunction
name="CountTokens"
access="public"
returntype="numeric"
output="false"
hint="Returns the number over which the tokenizer has iterated.">
<cfreturn VARIABLES.Instance.TokenIndex />
</cffunction>
<cffunction
name="HasMoreElements"
access="public"
returntype="boolean"
output="false"
hint="Checks to see if there are more elemnts to be returned.">
<cfreturn (VARIABLES.Instance.RawTokenIndex LT ArrayLen( VARIABLES.Instance.RawTokens )) />
</cffunction>
<cffunction
name="HasMoreTokens"
access="public"
returntype="boolean"
output="false"
hint="Checks to see if there are more elemnts to be returned (this just wraps around HasMoreElements()).">
<cfreturn THIS.HasMoreElements() />
</cffunction>
<cffunction
name="NextElement"
access="public"
returntype="string"
output="false"
hint="Returns the next element.">
<cfset var LOCAL = StructNew() />
<cfset LOCAL.Value = "" />
<cfset LOCAL.IsInValue = false />
<cfif Len( VARIABLES.Instance.Qualifier )>
<cfset VARIABLES.Instance.RawTokenIndex = (VARIABLES.Instance.RawTokenIndex + 1) />
<cfset LOCAL.Value = VARIABLES.Instance.RawTokens[ VARIABLES.Instance.RawTokenIndex ] />
<cfset LOCAL.Value = LOCAL.Value.ReplaceFirst( "^.{1}", "" ) />
<cfif (LOCAL.Value EQ (VARIABLES.Instance.Qualifier & VARIABLES.Instance.Qualifier))>
<cfset LOCAL.Value = "" />
<cfelseif (Left( LOCAL.Value, 1 ) EQ VARIABLES.Instance.Qualifier)>
<cfset LOCAL.Value = LOCAL.Value.ReplaceFirst( "^.{1}", "" ) />
<cfset LOCAL.Value = LOCAL.Value.ReplaceAll(
"\#VARIABLES.Instance.Qualifier#{2}",
"[[QUALIFIER]]"
) />
<cfif (Right( LOCAL.Value, 1 ) EQ VARIABLES.Instance.Qualifier)>
<cfset LOCAL.Value = LOCAL.Value.ReplaceFirst( ".{1}$", "" ) />
<cfelse>
<cfloop
index="VARIABLES.Instance.RawTokenIndex"
from="#(VARIABLES.Instance.RawTokenIndex + 1)#"
to="#ArrayLen( VARIABLES.Instance.RawTokens )#"
step="1">
<cfset LOCAL.TempValue = VARIABLES.Instance.RawTokens[ VARIABLES.Instance.RawTokenIndex ] />
<cfset LOCAL.TempValue = LOCAL.TempValue.ReplaceFirst( "^.{1}", "" ) />
<cfset LOCAL.TempValue = LOCAL.TempValue.ReplaceAll(
"\#VARIABLES.Instance.Qualifier#{2}",
"[[QUALIFIER]]"
) />
<cfif (Right( LOCAL.TempValue, 1 ) EQ VARIABLES.Instance.Qualifier)>
<cfset LOCAL.Value = (
LOCAL.Value &
VARIABLES.Instance.Delimiter &
LOCAL.TempValue.ReplaceFirst( ".{1}$", "" )
) />
<cfbreak />
<cfelse>
<cfset LOCAL.Value = (
LOCAL.Value &
VARIABLES.Instance.Delimiter &
LOCAL.TempValue
) />
</cfif>
</cfloop>
</cfif>
<cfset LOCAL.Value = LOCAL.Value.ReplaceAll(
"\[\[QUALIFIER\]\]",
VARIABLES.Instance.Qualifier
) />
</cfif>
<cfset VARIABLES.Instance.TokenIndex = (VARIABLES.Instance.TokenIndex + 1) />
<cfelse>
<cfset VARIABLES.Instance.RawTokenIndex = (VARIABLES.Instance.RawTokenIndex + 1) />
<cfset VARIABLES.Instance.TokenIndex = VARIABLES.Instance.RawTokenIndex />
<cfset LOCAL.Value = VARIABLES.Instance.RawTokens[ VARIABLES.Instance.RawTokenIndex ] />
<cfset LOCAL.Value = LOCAL.Value.ReplaceFirst( "^.{1}", "" ) />
</cfif>
<cfreturn LOCAL.Value />
</cffunction>
<cffunction
name="NextToken"
access="public"
returntype="string"
output="false"
hint="Returns the next element (this just wraps around NextElement()).">
<cfreturn THIS.NextElement() />
</cffunction>
</cfcomponent>