Practical Regular Expression Patterns in C# for String Validation and Extraction
Regular expressions provide a concise, robust mechanism for string manipulation—enabling validation, pattern-based extraction, and targeted substitution. Without them, developers often resort to fragile chains of IndexOf, Substring, and nested conditionals, increasing maintenance overhead and the risk of edge-case omissions.
To use regex functionality in C#, include the namespace:
using System.Text.RegularExpressions;
Validate Input Against a Pattern
/// <summary>
/// Determines whether the input string matches the specified pattern.
/// </summary>
/// <param name="pattern">The regular expression pattern to match.</param>
/// <param name="text">The string to test.</param>
/// <returns>True if the pattern is found; otherwise, false.</returns>
public static bool MatchesPattern(string pattern, string text)
{
return Regex.IsMatch(text, pattern, RegexOptions.IgnoreCase);
}
Extract All Matching Substrings
/// <summary>
/// Returns all substrings from the input that conform to the given pattern.
/// </summary>
/// <param name="pattern">The regex pattern.</param>
/// <param name="text">The source string.</param>
/// <returns>A list of matched values.</returns>
public static IReadOnlyList<string> FindAllMatches(string pattern, string text)
{
var matches = Regex.Matches(text, pattern);
return matches.Cast<Match>().Select(m => m.Value).ToList();
}
Retrieve First Match Only
/// <summary>
/// Returns the first substring matching the pattern, or empty string if none found.
/// </summary>
/// <param name="pattern">The regex pattern.</param>
/// <param name="text">The source string.</param>
/// <returns>The first matched value.</returns>
public static string FindFirstMatch(string pattern, string text)
{
var match = Regex.Match(text, pattern);
return match.Success ? match.Value : string.Empty;
}
Real-World Example: Parsing Motion Commands
Consider parsing motion instructions like xMove(1250,45000,Abs); or xMove(800,22000,Rel);. A non-regex approach requires manual index tracking and multiple type checks:
// Fragile and hard to extend
if (cmd.StartsWith("xMove") && cmd.Contains('(') && cmd.Contains(',') && cmd.EndsWith(";"))
{
// … complex parsing logic with error-prone offsets
}
A cleaner alternative uses regex for both validation and structured extraction:
const string CommandPattern = @"^xMove\(\d+,\d+,(Abs|Rel)\);$";
const string ParameterPattern = @"\d+|(Abs|Rel)";
if (MatchesPattern(CommandPattern, command))
{
var parts = FindAllMatches(ParameterPattern, command);
if (parts.Count == 3)
{
double targetPosition = double.Parse(parts[0]);
double velocity = double.Parse(parts[1]);
MovementMode mode = Enum.Parse<MovementMode>(parts[2], ignoreCase: true);
// proceed with validated data
}
}
Advanced Extraction Using Lookarounds
Given a string like LineTool.StartX[427], extract components without including delimiters:
LineTool→^\w+(?=\.)StartX→(?<=\.)\w+(?=\[)427→(?<=\[)\d+(?=\])
For strings wrapped in parentheses containing a dot (e.g., (a.b)), use minimal matching:
(?<=\().+?\..+?(?=\))
This ensures the shortest possible match between ( and ), requiring at least one character before and after the dot.