Count Occurences of Substring in a String

Hello all,

Just wondering if there is a CF function that will count the occurrences of a substring within a string. Can’t check Adobe LiveDocs right now because the server is down!

Thanks.

Oh boo, I spelled “occurrences” wrong in the title and I can’t edit it! Just thought I’d point that out before someone else does :slight_smile: .


<cfset occurrences
    = Len(Replace(string,substring,'','all'))
      / Len(substring) >

p.s. don’t never use adobe’s web site, it’s slower than cold glue, way too much stoopid “rich content” and online paper for my liking

i use this – http://www.cfquickdocs.com/

rudy? maybe im not following what it is you were trying to do there, but I don’t think that is what he is after.

Using this code:


<cfset variables.string = "the quick brown fox jumped over the red bridge" />
<cfset variables.substring = "the" />

<cfset occurrences = Len(Replace(variables.string,variables.substring,'','all')) / Len(variables.substring) >
    
<cfdump var="#occurrences#">

which should be counting the number of times the word “the” occurres, I get 13.3333, which I don’t think is correct. Or am I misusing your code?

I would use a function like this:


<cffunction name="countOccurrences" access="public" returntype="numeric" required="true">
    <cfargument name="string" type="string" required="True" />
    <cfargument name="subString" type="string" required="True" />
    
    <cfset VAR position = findNoCase(arguments.substring,arguments.string,1) />
    <cfset VAR count = 0 />
    
    <cfif len(trim(arguments.substring))>
        <cfloop condition="position NEQ 0">
            <cfset count = count + 1 />
            <cfset position = findNoCase(arguments.substring,arguments.string, position + len(trim(arguments.substring))) />
        </cfloop>
    <cfelse>
        <cfreturn 0 />
    </cfif>

<cfreturn count />
</cffunction>

then you can just call it whenever you need, pass it the full string, pass it the string you are looking for, and it returns a number of how many times it occurs.

aaargggggghhhhhhhhh my bad

<cfset occurrences
   = ( Len(string) -
       Len(Replace(string,substring,'','all'))
     ) / Len(substring) >

still a lot simpler than a loop, eh

(my experience with databases has taught me that any time you are doing anything in a loop, there’s probably a more efficient way)

:slight_smile:

I had a feeling that you just botched the code, in fact, I think you have given that same example out here before and I remember being impressed.

Yes, this will work, except there is a good chance you want replaceNoCase() instead of just replace(), depending on what you are doing.

bows to rudy’s algorithm genius

Yeah, I was wondering if I was just crazy and couldn’t get the code to work correctly :).

I ended up just writing my own function and it turned up basically like what rynoguill wrote. So, thanks for the responses!

please, please, oh do please try my solution, it works, i tested it