Introduction
In my fervent quest to improve upon notepad with notepad.net, I've added a feature to the tool to allow you to search using regular expression searches. Regular expressions are very useful for matching patterns in your text that span more than just matching exact letters. The example in figure 1 matches all words beginning with "acc". If you have never worked with regular expressions before, table 1 below shows you some of the regular expression symbols and their respective meaning.
Figure 1 - Notepad.NET's FindDialog using Regular Expressions
| Expression | Description | Example |
| . | Match any single character except new line character (wildcard) | c.t matches cat and cut , cit, cpt, c&t , etc. c..t matches curt, cant |
| [ ] | Matches a single character of a set of characters | c[au]t only matches cat and cut |
| [ ]+ | Matches one or more characters in a set of characters | c[a]+t matches cat and caat and caaat, c[a-z]+t matches cat, cut, clout, cakajhknmht [0-9]+ matches integer values [0-9a-z]+ matches alphanumeric expressions (note that for a set of one character, you could have also expressed c[a]+t as ca+t) |
| [ ]* | Matches zero or more characters in a set of characters | c[a]*t matches ct, cat and caat and caaat, etc. c[a-z]*t matches ct, cat, cut, clout, creawtt (note that for a set of one character, you could have also expressed c[a]*t as ca*t) |
| [ ]? | Matches zero or one time in a set of characters, used for optional characters |
c[a]?t matches ct, cat c[a-z]?t matches ct, cat, cut, cot, crt, etc. (note that for a set of one character, you could have also expressed c[a]?t as ca?t) |
| \ | escape character. used for special characters and for overriding regular expressions so they are recognized as literals | \n line feed \d digit, same as [0-9] \w alphanumeric character, same as [0-9a-z] \s space or lf character, same as [\t\n\r\f] \. period, must be escaped, since otherwise it would mean wildcard character \- dash must also be escaped, since otherwise it mean range of characters |
| {n} | character must appear exactly n times | ca{3}t matches only caaat c[a-z]{3}t matches cabct, caaat, coggt , cxyzt |
| {n,m} | character must appear between n and m times | ca{0,3}t matches only ct, cat, caat, caaat. |
| ( ) | used to apply regular expression operations to more than one consecutive character in an expression | c(at)+ matches cat, catat, catatatatat, c(at){2} matches only catat |
| ^ | Matches a character at the beginning of the line | ^T.+ matches all lines in the searchable string beginning with the letter T. e.g. matches the line Thanks for the coffee! (as long as Thanks is at the beginning of a line) Note: the meaning of ^ depends on whether the RegexOptions are set for Singleline or Multiline |
| $ | Matches a character at the end of the line | ^T.+P$ Matches all lines beginning with T and ending with P. Note: the meaning of $ depends on whether the RegexOptions are set for Singleline or Multiline |
Table 1 - Regular Expression Symbols, and how to use them.
So let's look at a few useful regular expressions. Say we wanted to find all social securities in a text document matching the form
ddd-dd-dddd
We need a regular expression that only allows numeric digits in groups of 3-2-4 including the hyphen. Using table 1, we come up with the following expression:
[0-9]{3}\-[0-9]{2}\-[0-9]{4}
This expression will only search for social security numbers matching three digits, hyphen, two digits, hyphen, 4 digits (e.g. 111-11-1111). If we want to make the hyphen optional, we could write the expression with the question mark (?) after each hyphen
[0-9]{3}\-?[0-9]{2}\-?[0-9]{4}
Now we can accept expressions of either 111-11-1111 or 111111111.
Perhaps we want to look for all email addresses. We know e-mail addresses are in the form [email protected] with certain allowable characters for x (including a period). An equivalent expression would be:
[A-Z0-9._%-]+@[A-Z0-9._%-]+\.[A-Z]{2,4}
In the next section we will explore the code that allows us to search a text box for regular expressions using the rich .NET framework.
The Design
The Find Dialog with regular expressions is implemented inside the FindDialog class shown in the UML Diagram in Figure 2. When Find Next is clicked inside the dialog (shown in figure 1) and regular expression is checked, the regular expression code kicks in by calling the FindNext method.

Figure 2 - NotePad.NET reverse engineered from C# using the WithClass UML Tool
The Code
The FindNext method inside the FindDialog takes 4 parameters: the search string we are looking for, whether or not the search string is case sensitive, the multiline text box control containing the entire text, and a boolean to indicate if the search string is a regular expression or not. The code is broken down into an if-else statement for handling whether or not the string we are looking for is case sensitive. Inside the if-else blocks we handle whether or not the search string is a regular expression or not. For searching regular expressions we use the System.Text.RegularExpressions namespace. This namespace contains the class Regex (which I guess stands for regular expression). Table 2 shows some of the members of this class to help you implement regular expression matching:
| Regex Member | Description |
| Regex (string pattern, RegexOptions) | Constructor to create a regex option. Passes regular expression to match, and options for how to treat the pattern matching engine (shown in table 3) |
| Match (string input, int startLocation)
|
Matches the first occurence of the input string, to the pattern passed to the constructor of the Regex object. Starts looking for the match at the startLocation of the input string. Returns a Match Object that indicates success of the match, position of the match, and length of the match. |
| IsMatch (string input) | Decides whether or not the regular expression is matched anywhere in the input string. |
Table 2 - Regex Members
With the Regex class, you construct an instance passing it the regular expression pattern you wish to match You can also pass a set of options (RegexOptions) into the regular expression constructor, such as whether or not to ignore case on your search. Table 3 shows a list of some of the useful RegexOptions:

Join the conversation! Your thoughts help the community grow.