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

  • On-demand Event Event Date: September 10, 2014 Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild." This loop of continuous delivery and continuous feedback is how the best mobile …

  • The explosion in mobile devices and applications has generated a great deal of interest in APIs. Today's businesses are under increased pressure to make it easy to build apps, supply tools to help developers work more quickly, and deploy operational analytics so they can track users, developers, application performance, and more. Apigee Edge provides comprehensive API delivery tools and both operational and business-level analytics in an integrated platform. It is available as on-premise software or through …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds