Search Strings for Patterns with the Match Classes

The previous article illustrated how to use the .NET Regex class to split strings, such as when you need to break a comma-delimited string into its separate components (or columns). This article covers how to search strings for patterns, where the found matches are returned via the MatchCollection and Match classes. The basic steps to using these classes are as follows:

  1. Construct a Regex object with the pattern for which you are searching.
  2. Call the Regex::Match method, passing the input value to be scanned. This method returns a boolean value indicating whether or not any matches were found.
  3. Retrieve the matches via the Regex::Matches property.
  4. Iterate the matches.

Searching for a Single Pattern Occurrence

In the following example, the code is searching a string for the first occurrence of a literal and then printing the found value (Match::Value) along with the position within the input string where that value was located (Match::Index). I've bolded the salient code for emphasis:

// Example of searching for a single literal or pattern occurrence
using namespace System::Text::RegularExpressions;
...
String* input = S"Tim, sometimes you have to accept that times are changing.";
String* pattern = S"tim";

Console::WriteLine(S"Searching '{0}' for '{1}'", input, pattern);

Regex* rex = new Regex(pattern);
Match* match = rex->Match(input);
if (match->Success)
{
  Console::WriteLine(S"Found '{0}' at position {1}",
                     match->Value,
                     __box(match->Index));

}

Searching for Multiple Matches with the MatchCollection Class

In the previous example, whereas the literal "tim" occurred several times in the input text, the code was designed to find only the first occurrence. Let's see how the code can be modified to use the MatchCollection class to enumerate all matches within a string.

In the following code, I've made several changes:

  • The Regex constructor takes a second argument of type RegexOptions that enables you to specify things, such as whether or not the search is case-sensitive. (For this example, I'm specifying RegexOptions::IgnoreCase so that the code locates all occurrences of "tim" regardless of case.)
  • The code is using the Regex::IsMatch method to first verify whether any matches are found enumerating the MatchCollection. You also can check the count of the MatchCollection object, so using either form is a subjective choice.
  • The MatchCollection object is retrieved via the Regex::Matches property. The MatchCollection object can be enumerated as any other .NET collection where the Count property indicates the number of objects held and individual objects are extracted via the collection's Item property.
String* input = S"Tim, sometimes you have to accept that times are changing.";
String* pattern = S"tim";

Console::WriteLine(S"Searching '{0}' for '{1}'", input, pattern);

Regex* rex = new Regex(pattern, RegexOptions::IgnoreCase);
if (rex->IsMatch(input))
{
  MatchCollection* matches = rex->Matches(input);		
  for (int i = 0; i  <matches->Count; i++)
  {
    Match* match = matches->Item[i];
    Console::WriteLine(S"Found '{0}' at position {1}",
                       match->Value, 
                       __box(match->Index));
  }
}

Enumerating Matches with the NextMatch Method

Did you know you can enumerate matches without the MatchCollection class? This is accomplished by using the Match::NextMatch method to enumerate through the matches of an input string. Here's an example that once again searches the same input string for occurrences of the literal "tim":

String* input = S"Tim, sometimes you have to accept that times are changing.";
String* pattern = S"tim";

Console::WriteLine(S"Searching '{0}' for '{1}'", input, pattern);

Regex* rex = new Regex(pattern, RegexOptions::IgnoreCase);
for (Match* match = rex->Match(input);
     match->Success;
     match = match->NextMatch())
{
  Console::WriteLine(S"Found '{0}' at position {1}",
                     match->Value, 
                     __box(match->Index));
}

Looking Ahead

So far, you've covered the basics of splitting strings and using the Match/MatchCollection classes. Future articles continue in the .NET implementation of regular expressions by delving into how to form regular expression patterns to find what you're looking for and the topics of groups and captures.



About the Author

Tom Archer - MSFT

I am a Program Manager and Content Strategist for the Microsoft MSDN Online team managing the Windows Vista and Visual C++ developer centers. Before being employed at Microsoft, I was awarded MVP status for the Visual C++ product. A 20+ year veteran of programming with various languages - C++, C, Assembler, RPG III/400, PL/I, etc. - I've also written many technical books (Inside C#, Extending MFC Applications with the .NET Framework, Visual C++.NET Bible, etc.) and 100+ online articles.

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • You've managed to piece together the "DREAM TEAM." Your tech staff works like a well-oiled machine, keeping your company humming and thriving. And then it happens: dissension. For whatever reason, your employees have grown unhappy and you find out they're searching for new employment or losing productivity. What did you do wrong? Did you hire the wrong people? Did your company push them away? Or is it a combination of numerous factors? Read this white paper to learn how to build an environment that fosters …

  • Get an in-depth look at the services and tools that the #1 cloud platform for creating next-gen apps offers to help you build apps faster. You'll learn how Salesforce gives you a competitive advantage with Platform as a Service like no other. Details include: Salesforce's Multitenant Cloud Infrastructure and Database App Builder that lets anyone build apps fast Force.com for building employee-facing apps Heroku for beautiful and engaging customer-facing apps

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date