Recipe 2.4 Finding All Occurrences of a Character Within a String
Problem
You need a way of searching a
string for multiple occurrences of a specific character.
Solution
Use
IndexOf in a loop to determine how many
occurrences of a character exist, as well as identify their location
within the string:
using System;
using System.Collections;
public static int[] FindAllOccurrences(char matchChar, string source)
{
return (FindAllOccurrences(matchChar, source, -1, false));
}
public static int[] FindAllOccurrences(char matchChar, string source,
int maxMatches)
{
return (FindAllOccurrences(matchChar, source, maxMatches, false));
}
public static int[] FindAllOccurrences(char matchChar, string source,
bool caseSensitivity)
{
return (FindAllOccurrences(matchChar, source, -1, caseSensitivity));
}
public static int[] FindAllOccurrences(char matchChar, string source,
int maxMatches, bool caseSensitivity)
{
ArrayList occurrences = new ArrayList( );
int foundPos = -1; // -1 represents not found
int numberFound = 0;
int startPos = 0;
char tempMatchChar = matchChar;
string tempSource = source;
if (!caseSensitivity)
{
tempMatchChar = char.ToUpper(matchChar);
tempSource = source.ToUpper( );
}
do
{
foundPos = tempSource.IndexOf(matchChar, startPos);
if (foundPos > -1)
{
startPos = foundPos + 1;
numberFound++;
if (maxMatches > -1 && numberFound > maxMatches)
{
break;
}
else
{
occurrences.Add(foundPos);
}
}
}while (foundPos > -1);
return ((int[])occurrences.ToArray(typeof(int)));
}
Discussion
The FindAllOccurrences method is overloaded to
allow the last two parameters (maxMatches and
caseSensitivity) to be set to a default value if
the developer chooses not to pass in one or both of these parameters.
The maxMatches parameter defaults to
-1, indicating that all matches are to be found.
The caseSensitivity parameter defaults to
false to allow for a case-insensitive search.
The FindAllOccurrences method starts out by
determining whether case sensitivity is turned on. If
false was passed in to the
caseSensitivity parameter, both
matchChar and source are set to
all uppercase. This prevents a case-sensitive search.
The main loop in this method is a simple do loop
that terminates when foundPos returns
-1, meaning that no more
matchChar characters can be found in the
source string. We use a do loop
so that the IndexOf operation would be executed at
least one time before the check in the while
clause is performed to determine whether there are any more character
matches to be found in the source string.
Once a match is found by the IndexOf method, the
numberFound variable is incremented by one to
indicate that another match was found, and
startPos is moved past the previously found match
to indicate where the next IndexOf operation
should start. The startPos is increased to the
starting position of the last match found plus one. The
+1 is needed so that we do not keep matching the
same character that was previously matched. An infinite loop would
occur in the code if at least one match was found in the
source string.
Finally, a check is made to determine whether we are done searching
for matchChar characters. If the
maxMatches parameter is set to
-1, the code keeps searching until it arrives at
the end of the source string. Any other number
indicates the maximum number of matchChar
characters to search for. The maxMatches parameter
limits the number of matches that can be made in the
source string. If this check indicates that we are
able to keep this match, it is stored in the
occurrences ArrayList.
|