Regular Expressions

Regular expressions (regex) are powerful patterns used to match and manipulate text. Think of them as a search tool on steroids - instead of just finding exact words, you can find patterns like "all email addresses" or "phone numbers in a specific format."

In Dart, regular expressions are handled by the RegExp class, which provides methods to search, match, and replace text based on patterns.

Creating Regular Expressions

You can create a RegExp object in two ways:

// Using the RegExp constructor
RegExp regex1 = RegExp(r'\d+'); // Matches one or more digits

// Using the r prefix for raw strings (recommended)
RegExp regex2 = RegExp(r'[a-zA-Z]+'); // Matches one or more letters

The r prefix creates a raw string, which is helpful because regex patterns often contain backslashes that would otherwise need to be escaped.

Common Regex Patterns

PatternDescriptionExample
\dAny digit (0-9)\d+ matches "123"
\wAny word character (letters, digits, underscore)\w+ matches "hello_123"
\sAny whitespace character\s+ matches spaces, tabs
.Any character except newlinea.c matches "abc", "axc"
+One or more of the precedinga+ matches "a", "aa", "aaa"
*Zero or more of the precedinga* matches "", "a", "aa"
?Zero or one of the precedinga? matches "", "a"
[]Character class[abc] matches "a", "b", or "c"
^Start of string^hello matches "hello world"
$End of stringworld$ matches "hello world"

Basic Regex Operations

Checking if a pattern matches

String text = "Hello, my phone number is 123-456-7890";
RegExp phonePattern = RegExp(r'\d{3}-\d{3}-\d{4}');

bool hasPhone = phonePattern.hasMatch(text);
print(hasPhone); // true

Finding the first match

String email = "Contact us at [email protected] for help";
RegExp emailPattern = RegExp(r'\w+@\w+\.\w+');

RegExpMatch? match = emailPattern.firstMatch(email);
if (match != null) {
  print(match.group(0)); // [email protected]
}

Finding all matches

String text = "Call 123-456-7890 or 987-654-3210";
RegExp phonePattern = RegExp(r'\d{3}-\d{3}-\d{4}');

Iterable<RegExpMatch> matches = phonePattern.allMatches(text);
for (RegExpMatch match in matches) {
  print(match.group(0));
}
// Output:
// 123-456-7890
// 987-654-3210

String Methods with Regex

Dart strings have built-in methods that work with regular expressions:

Replacing text

String text = "The price is $100 and $200";
RegExp pricePattern = RegExp(r'\$\d+');

// Replace first occurrence
String replaced = text.replaceFirst(pricePattern, 'PRICE');
print(replaced); // The price is PRICE and $200

// Replace all occurrences
String replacedAll = text.replaceAll(pricePattern, 'PRICE');
print(replacedAll); // The price is PRICE and PRICE

Splitting strings

String data = "apple,banana;orange:grape";
RegExp separators = RegExp(r'[,;:]');

List<String> fruits = data.split(separators);
print(fruits); // [apple, banana, orange, grape]

Practical Examples

Validating an email address

bool isValidEmail(String email) {
  RegExp emailRegex = RegExp(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$');
  return emailRegex.hasMatch(email);
}

print(isValidEmail("[email protected]")); // true
print(isValidEmail("invalid-email"));    // false

Extracting numbers from text

String text = "I have 5 apples and 10 oranges";
RegExp numberPattern = RegExp(r'\d+');

List<int> numbers = numberPattern
    .allMatches(text)
    .map((match) => int.parse(match.group(0)!))
    .toList();

print(numbers); // [5, 10]

Regex Flags

You can add flags to modify how the regex behaves:

// Case-insensitive matching
RegExp caseInsensitive = RegExp(r'hello', caseSensitive: false);
print(caseInsensitive.hasMatch("HELLO")); // true

// Multiline mode
RegExp multiline = RegExp(r'^start', multiLine: true);

Regular expressions might seem intimidating at first, but they're incredibly useful for text processing tasks. Start with simple patterns and gradually work your way up to more complex ones as you get comfortable with the syntax!