Expresso Overview

Expresso is a tool for building and testing .NET regular expressions. It simplifies the process of developing regular expressions for use in ASP.NET or Windows applications by providing the following features:

  • Build complex expressions by selecting components from a palette
  • Test expressions against real or sample input data
  • Display all matches in a tree structure showing captured groups, and all captures within a group
  • Build replacement strings and test the match and replace functionality
  • Highlight matched text in the input data
  • Automatically test for syntax errors
  • Generate Visual Basic, C#, or Managed C++ code that can be incorporated directly into programs
  • Read or save regular expressions and input data
  • Keep track of a history of previously used expressions
  • Manage a library of useful regular expressions
  • Perform timing tests to optimize the performance of your expressions
  • Decode expressions, breaking them into components that are described in English
  • Automatically incorporate an English language description of an expression into code comments
  • Run matches against a portion of the full regular expression

For More Help

  • Getting Started with Expresso
  • Learning .NET Regular Expressions with Expresso
  • Using the Expression Builder
  • Using the Expression Library
  • Analyze Your Expressions
  • Generating Computer Code
  • Compiling an Assembly File
  • Performance Testing
  • How to Register Expresso
  • About Expresso

Next Topic: Getting Started with Expresso

For More Help

© 2004 Ultrapico. All rights reserved.


Getting Started with Expresso

Play with the Sample Project

Select Open Sample Project from the Edit menu. This loads sample text, a library of regular expressions, a replacement string, and the Dates example as the current regular expression. Click the Run Match button. A list of successful matches will appear in the tree view in the lower right hand corner. Select and expand nodes to highlight the matched text. Now click the Replace button. This substitutes portions of the text using the replacement string. In the results box, notice that each date was replaced with the matched text followed by the date in a different format.

Adjust the User Interface

There are three horizontal splitters and one vertical splitter to adjust the size of the different tools within Expresso. Move these around to suit your preference. The settings will be preserved when you exit the program. You can also adjust the font and word wrap using the Format menu.

Experiment with the Tabs

Click on each of the major tabs. The regular expression is always displayed, but the tabs show additional elements as described here:

  • Regular Expression - Edit only the regular expression
  • Replacement String - Edit the string used when "Replace" command is run
  • Expression Library - Select regular expressions from a library
  • Recent Expressions - Select a recently used regular expression
  • Analyzer - Parse the expression and describe it in plain English
  • Options - Display and change the regular expression options

Select the Expression Library tab, select one of the items, and click Run Match. Try this for several of the expressions and review the results. Select the Analyzer tab to see a description of the regular expression in ordinary English. If you click on a node in the Analyzer, the corresponding part of your regular expression will be highlighted. Now select the Recent Expressions tab. You should see a list of all the expressions for which you have run a match or replace operation.

Partial Matching

A novel feature of Expresso is the ability to select just a portion of a regular expression to run against the sample text. Try this by first selecting the Zip Codes example. Use the mouse to select a portion of the text in the regular expression text box. Select all the text up to and including the hyphen and then click Partial Match. Only the selected text is used as the regular expression. If you click Exclude Match, the selected text will be excluded from the regular expression before the match is done. This feature enables debugging of portions of a regular expression without having to modify the expression.

Using the Builder

Click on the Show Builder button to see the tool for building regular expressions without having to remember the complex syntax. Try a simple example to see how it works.

Next Topic: Using the Expression Builder

For More Help


The 30 Minute Regex Tutorial

Learning .NET Regular Expressions with Expresso

A familiar concept in many computer systems is the use of "wildcard" characters for pattern matching. If you want to find all the Microsoft Word files in a Windows directory, you search for "*.doc", knowing that the asterisk is interpreted as a wildcard that can match any sequence of characters.

In writing programs or web pages that manipulate text, it is frequently necessary to do this kind of pattern matching with much more complex patterns. Regular expressions were invented for this purpose. The .NET framework provides a powerful class library that makes it easy to include regular expressions in your applications. With this library, you can readily search and replace text, decode complex headers, parse languages, or validate text.

The best way to learn the arcane syntax of regular expressions is by experimenting with examples. This article introduces the basics of regular expressions, giving many examples that are included in an Expresso library file. Expresso can be used to try out the examples and to experiment with your own regular expressions.

Let's get started!

Some Simple Examples

Searching for Elvis

Suppose you spend your time scanning documents looking for evidence that Elvis is still alive. You could search with the following regular expression:

1. elvis Find elvis

This is a perfectly valid regular expression that searches for an exact sequence of characters. In .NET, you can easily set options to ignore the case of characters, so this expression will match "Elvis", "ELVIS", or "eLvIs". Unfortunately, it will also match the last five letters of the word "pelvis". We can improve the expression as follows:

2. \belvis\b Find elvis as a whole word

Now things are getting a little more interesting. The "\b" is a special code that means, "match the position at the beginning or end of any word". This expression will only match complete words spelled "elvis" with any combination of lower case or capital letters.

Suppose you want to find all lines in which the word "elvis" is followed by the word "alive." The period or dot "." is a special code that matches any character other than a newline. The asterisk "*" means repeat the previous term as many times as necessary to guarantee a match. Thus, ".*" means "match any number of characters other than newline". It is now a simple matter to build an expression that means "search for the word 'elvis' followed on the same line by the word 'alive'."

3. \belvis\b.*\balive\b Find text with "elvis" followed by "alive"

With just a few special characters we are beginning to build powerful regular expressions and they are already becoming hard for we humans to read.

Let's try another example.

Determining the Validity of Phone Numbers

Suppose your web page collects a customer's seven-digit phone number and you want to verify that the phone number is in the correct format, "xxx-xxxx", where each "x" is a digit. The following expression will search through text looking for such a string:

4. \b\d\d\d-\d\d\d\d Find seven-digit phone number

Each "\d" means "match any single digit". The "-" has no special meaning and is interpreted literally, matching a hyphen. To avoid the annoying repetition, we can use a shorthand notation that means the same thing:

5. \b\d{3}-\d{4}  Find seven-digit phone number a better way

The "{3}" following the "\d" means "repeat the preceding character three times".

Let's learn how to test this expression.

Expresso

If you don't find regular expressions hard to read, I suspect you are either an idiot savant or a visitor from another planet. The syntax can be imposing for anyone who does not use regular expressions frequently. This makes errors common and creates a need for a simple tool for building and testing expressions. Many such tools exist, but I'm partial to my own, Expresso, originally launched on the CodeProject. Version 2.0 is shown here. For later versions, check the website at http://www.ultrapico.com .

To get started, install Expresso and select the Tutorial from the Windows Program menu. Each example can be selected using the tab labeled "Expression Library".

Figure 1. Expresso running example 5

Start by selecting the first example, "1. Find Elvis". Click Run Match and look at the TreeView on the right. Note there are several matches. Click on each to show the location of the match in the sample text. Run the second and third examples, noting that the word "pelvis" no longer matches. Finally, run the fourth and fifth examples; both should match the same numbers in the text. Try removing the initial "\b" and note that part of a Zip Code matched the format for a phone number.

Basics of .NET Regular Expressions

Let's explore some of the basics of regular expressions in .NET.

Special Characters

You should get to know a few characters with special meaning. You already met "\b", ".", "*", and "\d". To match any whitespace characters, like spaces, tabs, and newlines, use "\s" . Similarly, "\w" matches any alphanumeric character.

Let's try a few more examples:

6. \ba\w*\b Find words that start with the letter a

This works by searching for the beginning of a word (\b), then the letter "a", then any number of repetitions of alphanumeric characters (\w*), then the end of a word (\b).

7. \d+ Find repeated strings of digits

Here, the "+" is similar to "*", except it requires at least one repetition.

8. \b\w{6}\b Find six letter words

Try these in Expresso and start experimenting by inventing your own expressions. Here is a table of some of the characters with special meaning:

. | Match any character except newline
\w | Match any alphanumeric character
\s | Match any whitespace character
\d | Match any digit
\b | Match the beginning or end of a word
^ | Match the beginning of the string
$ | Match the end of the string

Table 1. Commonly used special characters for regular expressions

In the beginning

The special characters "^" and "$" are used when looking for something that must start at the beginning of the text and/or end at the end of the text. This is especially useful for validating input in which the entire text must match a pattern. For example, to validate a seven-digit phone number, you might use:

9. ^\d{3}-\d{4}$ Validate a seven-digit phone number

This is the same as example (5), but forced to fill the whole text string, with nothing else before or after the matched text. By setting the "Multiline" option in .NET, "^" and "$" change their meaning to match the beginning and end of a single line of text, rather than the entire text string. The Expresso example uses this option.

Escaped characters

A problem occurs if you actually want to match one of the special characters, like "^" or "$". Use the backslash to remove the special meaning. Thus, "\^", "\.", and "\\", match the literal characters "^", ".", and "\", respectively.

Repetitions

You've seen that "{3}" and "*" can be used to indicate repetition of a single character. Later, you'll see how the same syntax can be used to repeat entire subexpressions. There are several other ways to specify a repetition, as shown in this table:

* | Repeat any number of times
+ | Repeat one or more times
? | Repeat zero or one time
{n} | Repeat n times
{n,m} | Repeat at least n, but no more than m times
{n,} | Repeat at least n times

Table 2. Commonly used quantifiers

Let's try a few more examples:

10. \b\w{5,6}\b Find all five and six letter words

11. \b\d{3}\s\d{3}-\d{4} Find ten digit phone numbers

12. \d{3}-\d{2}-\d{4} Social security number

13. ^\w* The first word in the line or in the text

Try the last example with and without setting the "Multiline" option, which changes the meaning of "^".

Character Classes

It is simple to find alphanumerics, digits, and whitespace, but what if we want to find anything from some other set of characters? This is easily done by listing the desired characters within square brackets. Thus, "[aeiou]" matches any vowel and "[.?!]" matches the punctuation at the end of a sentence. In this example, notice that the "." And "?" lose their special meanings within square brackets and are interpreted literally. We can also specify a range of characters, so "[a-z0-9]" means, "match any lowercase letter of the alphabet, or any digit".

Let's try a more complicated expression that searches for telephone numbers.

14. \(?\d{3}[) ]\s?\d{3}[- ]\d{4} A ten digit phone number

This expression will find phone numbers in several formats, like "(800) 325-3535" or "650 555 1212". The "\(?" searches for zero or one left parentheses, "[) ]" searches for a right parenthesis or a space. The "\s?" searches for zero or one whitespace characters. Unfortunately, it will also find cases like "650) 555-1212" in which the parenthesis is not balanced. Below, you'll see how to use alternatives to eliminate this problem.

Negation

Sometimes we need to search for a character that is NOT a member of an easily defined class of characters. The following table shows how this can be specified.

\W | Match any character that is NOT alphanumeric
\S | Match any character that is NOT whitespace
\D | Match any character that is NOT a digit
\B | Match a position that is NOT the beginning or end of a word
[^x] | Match any character that is NOT x
[^aeiou] | Match any character that is NOT one of the characters aeiou

Table 3. How to specify what you don't want

15. \S+  All strings that do not contain whitespace characters

Later, we'll see how to use "lookahead" and "lookbehind" to search for the absence of more complex patterns.

Alternatives

To select between several alternatives, allowing a match if either one is satisfied, use the pipe "|" symbol to separate the alternatives. For example, Zip Codes come in two flavors, one with 5 digits, the other with 9 digits and a hyphen. We can find either with this expression:

16. \b\d{5}-\d{4}\b|\b\d{5}\b Five and nine digit Zip Codes

When using alternatives, the order is important since the matching algorithm will attempt to match the leftmost alternative first. If the order is reversed in this example, the expression will only find the 5 digit Zip Codes and fail to find the 9 digit ones. We can use alternatives to improve the expression for ten digit phone numbers, allowing the area code to appear either delimited by whitespace or parenthesis:

17. (\(\d{3}\)|\d{3})\s?\d{3}[- ]\d{4} Ten digit phone numbers, a better way

Grouping

Parentheses may be used to delimit a subexpression to allow repetition or other special treatment. For example:

18. (\d{1,3}\.){3}\d{1,3} A simple IP address finder

The first part of the expression searches for a one to three digit number followed by a literal period "\.". This is enclosed in parentheses and repeated three times using the "{3}" quantifier, followed by the same expression without the trailing period.

Unfortunately, this example allows IP addresses with arbitrary one, two, or three digit numbers separated by periods even though a valid IP address cannot have numbers larger than 255. It would be nice to arithmetically compare a captured number N to enforce N<256, but this is not possible with regular expressions alone. The next example tests various alternatives based on the starting digits to guarantee the limited range of numbers by pattern matching. This shows that an expression can become cumbersome even when looking for a pattern that is simple to describe.

19. ((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?) IP finder

Expresso Analyzer View

Figure 2. Expresso's analyzer view showing example 17

Expresso has a feature that diagrams expressions in a Tree structure, explaining what each piece means. When debugging an expression, this can help zoom in on the part that is causing trouble. Try this by selecting example (17) and then using the Analyze button. Select nodes in the tree and expand them to explore the structure of this regular expression as shown in the figure. After highlighting a node, you can also use the Partial Match or Exclude Match buttons to run a match using just the highlighted portion of the regular expression or using the regular expression with the highlighted portion excluded.

When subexpressions are grouped with parentheses, the text that matches the subexpression is available for further processing in a computer program or within the regular expression itself. By default, groups are numbered sequentially as encountered in reading from left to right, starting with 1. This automatic numbering can be seen in Expresso's skeleton view or in the results shown after a successful match.

A "backreference" is used to search for a recurrence of previously matched text that has been captured by a group. For example, "\1" means, "match the text that was captured by group 1". Here is an example:

20. \b(\w+)\b\s*\1\b Find repeated words

This works by capturing a string of at least one alphanumeric character within group 1 "(\w+)", but only if it begins and ends a word. It then looks for any amount of whitespace "\s*" followed by a repetition of the captured text "\1" ending at the end of a word.

It is possible to override the automatic numbering of groups by specifying an explicit name or number. In the above example, instead of writing the group as "(\w+)", we can write it as "(?<Word>\w+)" to name this capture group "Word". A backreference to this group is written "\k<Word>". Try this example:

21. \b(?<Word>\w+)\b\s*\k<Word>\b Capture repeated word in a named group

Test this in Expresso and expand the match results to see the contents of the named group.

Using parentheses, there are many special purpose syntax elements available. Some of the most common are summarized in this table:

Captures |
(exp) | Match exp and capture it in an automatically numbered group
(?<name>exp) | Match exp and capture it in a group named name
(?:exp) | Match exp, but do not capture it
Lookarounds |
(?=exp) | Match any position preceding a suffix exp
(?<=exp) | Match any position following a prefix exp
(?!exp) | Match any position after which the suffix exp is not found
(?<!exp) | Match any position before which the prefix exp is not found
Comment |
(?#comment) | Comment

Table 4. Commonly used Group Constructs

We've already talked about the first two. The third "(?:exp)" does not alter the matching behavior, it just doesn't capture it in a named or numbered group like the first two.

Positive Lookaround

The next four are so-called lookahead or lookbehind assertions. They look for things that go before or after the current match without including them in the match. It is important to understand that these expressions match a position like "^" or "\b" and never match any text. For this reason, they are known as "zero-width assertions". They are best illustrated by example:

"(?=exp)" is the "zero-width positive lookahead assertion". It matches a position in the text that precedes a given suffix, but doesn't include the suffix in the match:

22. \b\w+(?=ing\b) The beginning of words ending with "ing"

"(?<=exp)" is the "zero-width positive lookbehind assertion". It matches the position following a prefix, but doesn't include the prefix in the match:

23. (?<=\bre)\w+\b The end of words starting with "re"

Here is an example that could be used repeatedly to insert commas into numbers in groups of three digits:

24. (?<=\d)\d{3}\b Three digits at the end of a word, preceded by a digit

Here is an example that looks for both a prefix and a suffix:

25. (?<=\s)\w+(?=\s) Alphanumeric strings bounded by whitespace

Negative Lookaround

Earlier, I showed how to search for a character that is not a specific character or the member of a character class. What if we simply want to verify that a character is not present, but don't want to match anything? For example, what if we are searching for words in which the letter "q" is not followed by the letter "u"? We could try:

26. \b\w*q[^u]\w*\b Words with "q" followed by NOT "u"

Run the example and you will see that it fails when "q" is the last letter of a word, as in "Iraq". This is because "[^q]" always matches a character. If "q" is the last character of the word, it will match the whitespace character that follows, so in the example the expression ends up matching two whole words. Negative lookaround solves this problem because it matches a position and does not consume any text. As with positive lookaround, it can also be used to match the position of an arbitrarily complex subexpression, rather than just a single character. We can now do a better job:

27. \b\w*q(?!u)\w*\b Search for words with "q" not followed by "u"

We used the "zero-width negative lookahead assertion", "(?!exp)", which succeeds only if the suffix "exp" is not present. Here is another example:

28. \d{3}(?!\d) Three digits not followed by another digit

Similarly, we can use "(?<!exp)", the "zero-width negative lookbehind assertion", to search for a position in the text at which the prefix "exp" is not present:

29. (?<![a-z ])\w{7} Strings of 7 alphanumerics not preceded by a letter or space

Here is one more example using lookaround:

30. (?<=<(\w+)>).*(?=<\/\1>) Text between HTML tags

This searches for an HTML tag using lookbehind and the corresponding closing tag using lookahead, thus capturing the intervening text but excluding both tags.

Comments please

Another use of parentheses is to include comments using the "(?#comment)" syntax. A better method is to set the "Ignore Pattern Whitespace" option, which allows whitespace to be inserted in the expression and then ignored when the expression is used. With this option set, anything following a number sign "#" at the end of each line of text is ignored. For example, we can format the preceding example like this:

31. Text between HTML tags, with comments

     (?<=       # Search for a prefix, but exclude it
       <(\w+)>  # Match a tag of alphanumerics within angle brackets
     )          # End the prefix

     .*         # Match any text

     (?=        # Search for a suffix, but exclude it
       <\/\1>   # Match the previously captured tab preceded by "/"
     )          # End the suffix

Greedy and Lazy

When a regular expression has a quantifier that can accept a range of repetitions (like ".*"), the normal behavior is to match as many characters as possible. Consider the following regular expression:

32. a.*b The longest string starting with a and ending with b

If this is used to search the string "aabab", it will match the entire string "aabab". This is called "greedy" matching. Sometimes, we prefer "lazy" matching in which a match using the minimum number of repetitions is found. All the quantifiers in Table 2 can be turned into "lazy" quantifiers by adding a question mark "?". Thus "*?" means "match any number of repetitions, but use the smallest number of repetitions that still leads to a successful match". Now let's try the lazy version of example (32):

33. a.*?b The shortest string starting with a and ending with b

If we apply this to the same string "aabab" it will first match "aab" and then "ab".

*? | Repeat any number of times, but as few as possible
+? | Repeat one or more times, but as few as possible
?? | Repeat zero or one time, but as few as possible
{n,m}? | Repeat at least n, but no more than m times, but as few as possible
{n,}? | Repeat at least n times, but as few as possible

Table 5. Lazy quantifiers

What did we leave out?

I've described a rich set of elements with which to begin building regular expressions; but I left out a few things that are summarized in the following table. Many of these are illustrated with additional examples in the project file. The example number is shown in the left-hand column of this table.

# | Syntax | Description
 | \a | Bell character
 | \b | Normally a word boundary, but within a character class it means backspace
 | \t | Tab
34 | \r | Carriage return
 | \v | Vertical tab
 | \f | From feed
35 | \n | New line
 | \e | Escape
36 | \nnn | Character whose ASCII octal code is nnn
37 | \x nn | Character whose hexadecimal code is nn
38 | \u nnnn | Character whose Unicode is nnnn
39 | \c N | Control N character, for example carriage return (Ctrl-M) is \cM
40 | \A | Beginning of a string (like ^ but does not depend on the multiline option)
41 | \Z | End of string or before \n at end of string (ignores multiline)
 | \z | End of string (ignores multiline)
42 | \G | Beginning of the current search
43 | \p{name} | Any character from the Unicode class named name, for example \p{IsGreek}
 | (?>exp) | Greedy subexpression, also known as a non-backtracking subexpression. This is matched only once and then does not participate in backtracking.
44 | (?<x>-<y>exp) or (?-<y>exp) | Balancing group. This is complicated but powerful. It allows named capture groups to be manipulated on a push down/pop up stack and can be used, for example, to search for matching parentheses, which is otherwise not possible with regular expressions. See the example in the project file.
45 | (?im-nsx:exp) | Change the regular expression options for the subexpression exp
46 | (?im-nsx) | Change the regular expression options for the rest of the enclosing group
 | (?(exp)yes|no) | The subexpression exp is treated as a zero-width positive lookahead. If it matches at this point, the subexpression yes becomes the next match, otherwise no is used.
 | (?(exp)yes) | Same as above but with an empty no expression
 | (?(name)yes|no) | This is the same syntax as the preceding case. If name is a valid group name, the yes expression is matched if the named group had a successful match, otherwise the no expression is matched.
47 | (?(name)yes) | Same as above but with an empty no expression

Table 6. Everything we left out. The left-hand column shows the number of an example in the project file that illustrates this construct.

Conclusion

We've given many examples to illustrate the essential features of .NET regular expressions, emphasizing the use of a tool like Expresso to test and experiment.


Using the Expression Builder

Expresso enables you to create regular expressions without having to remember an arcane syntax. Rather than explain all the options in the Builder, it is best to learn by trying. Let's create an expression to search for all words that begin with a single uppercase letter and that are followed by at least one whitespace character, which we do not want to include in the match. Start by loading the sample project from the File menu. Create the regular expression as follows:

  1. Clear the current regular expression
  2. Using the Options tab, turn off the Ignore Case option
  3. Click the Show Builder button
  4. Create the search for a single uppercase letter as follows:

    Select the Characters and Repetitions tab

    Select Named Class

    Select Uppercase Letters from the list box

    Select Just Once

    Make sure Match only if absent is NOT checked

    Click Insert to insert this into the regular expression

  5. Create the search for any number of alphanumeric characters:

    Select Alphanumeric

    Select Any Number

    Click Insert

  6. Create the search for at least one whitespace character, but exclude it from the match:

    Select the Groups and Options tab

    Select Match suffix but exclude it

    Click Insert

    Select the Characters and Repetitions tab

    Select Whitespace

    Select One or More

    Click Insert

The regular expression should now look like this:

\p{Lu}\w*(?=\s+)

Click Run Match to see if it works!

Where does the inserted text go?

  • Clicking Insert puts the new subexpression into the regular expression at the position of the cursor in the current regular expression
  • If a portion of the regular expression is highlighted, Insert will replace that text
  • After using Insert, the regular expression cursor is normally positioned at the end of the text that was just inserted
  • If a group is inserted, the cursor is positioned just before the closing parenthesis, where the contents of the group are expected
  • When you use Insert from the Substitutions page, the text is inserted into the replacement string instead of the regular expression

Next Topic: Using the Expression Library


Using the Expression Library

Expresso comes with a library of built-in regular expressions and allows you to build your own library. Each expression in the library has its own set of regular expression options and a short description. Expressions from the library are always available from the Expression Library tab. You may also select or edit expressions in the library using the Library dialog box.

Library Dialog Box

The dialog box displays both the expression library on the left and the list of recently used expressions on the right. Selecting an expression from either list will select it as the current regular expression. To add a recently used expression to the library, select it and then click the double arrow button, which will add it to the library and prompt you for a description. When you click on an item in the library, you may delete it, move it to a different position in the list, or edit the description, regular expression, and options.

Adding Expressions using the Menu

The easiest way to add an item to the library is using the Save Expression to Library command in the Library menu. This will prompt for a description and then add the item to the end of the library.

Working with Library Files

Normally, you will probably want to use the same library in all your projects and let the library grow as you add more expressions. It is also possible to maintain expression libraries in files using the Read, Save, and Append commands in the Library menu. There is also a command to restore the default expression library.

To embed a library as part of a project file, use the Project Options command in the File menu. Click on the Advanced tab of the project options dialog. By clicking the Save Library to Project File button, the library will be saved to the current project file. Whenever that file is subsequently loaded or saved, the expression library will be restored or saved.

Next Topic: Analyze your Expressions


Using the Analyzer

Complex regular expressions can be notoriously obtuse to read. It is helpful to let the computer decode the expression to display its elements in plain English. This is especially useful for decoding expressions that you did not write yourself or that you wrote long ago. For the same reasons, it is useful to include this kind of analysis as comments in your computer code.

An Example

For example, the Dates expression looks like this in Regexese:

(?<Month>\d{1,2})/(?<Day>\d{1,2})/(?<Year>(?:\d{4}|\d{2}))

and like this to the Analyzer:

[Month]: A named capture group. [\d{1,2}]
Any digit, between 1 and 2 repetitions
/
[Day]: A named capture group. [\d{1,2}]
Any digit, between 1 and 2 repetitions
/
[Year]: A named capture group. [(?:\d{4}|\d{2})]
Match expression but don't capture it. [\d{4}|\d{2}]
Select from 2 alternatives
Any digit, exactly 4 repetitions
Any digit, exactly 2 repetitions

Expresso displays this analysis on the Analyzer tab page in an expandable tree structure whenever you run a match, click on the Analyzer tab, or run Analyze from the Tools menu or Toolbar. By selecting a node in the tree, you will highlight that portion of the regular expression. In addition to helping you understand the expression, this can be used to highlight text that you want to modify with the Builder or to run a Partial Match.

Including the Analysis in Code Comments

To include the analysis in the comments generated in your code, be sure to click the checkbox in Project Options, available from the File menu.

Next Topic: Code Generation


Generating Computer Code

Once you have developed and debugged a regular expression, Expresso makes it easy to insert that expression into your code, with descriptive comments.

Setting Code Generation Options

The Project Options dialog (available from the File menu) allows you to set properties that will be used for code generation. This includes the desired programming language (Visual Basic, C#, or Managed C++), the variable name that will be used in your code for this regular expression, the access level (public, private, or protected), whether or not this is a static object, and a description to be included in the comments. You may also check an option that runs the Analyzer to generate comments that decode the regular expression into readable text.

The programming language can also be changed using Select Programming Language command in the Tools menu.

Generating Code

The Tools menu provides commands to view the code within the Expresso window, to write the code to a file, or to copy the code to the clipboard. Here is an example of C# code generated using the Dates example:

// using System.Text.RegularExpressions;

/// <summary>
/// Regular expression built for C# on: Mon, Mar 22, 2004, 09:31:53 AM
/// Using Expresso Version: 2.0.1541, http://www.ultrapico.com
///
/// Search for a date in Month/Day/Year format
///
/// A description of the regular expression:
///
/// [Month]: A named capture group. [\d{1,2}]
/// Any digit, between 1 and 2 repetitions
/// /
/// [Day]: A named capture group. [\d{1,2}]
/// Any digit, between 1 and 2 repetitions
/// /
/// [Year]: A named capture group. [(?:\d{4}|\d{2})]
/// Match expression but don't capture it. [\d{4}|\d{2}]
/// Select from 2 alternatives
/// Any digit, exactly 4 repetitions
/// Any digit, exactly 2 repetitions
///
///
/// </summary>
public Regex MyRegex = new Regex(
@"(?<Month>\d{1,2})/(?<Day>\d{1,2})/(?<Year>(?:\d{4}|\d{2}))",
RegexOptions.IgnoreCase
| RegexOptions.CultureInvariant
| RegexOptions.IgnorePatternWhitespace
| RegexOptions.Compiled
);

Next Topic: Compile to an Assembly File


Compiling an Assembly File

To create a precompiled version of your regular expression in an assembly file, use the Compile to Assembly command from the Tools menu. A dialog box will prompt for the name of the file, the namespace, the class name, and whether or not you want the regular expression to be publicly visible. Click Compile to create the assembly file and be sure to reference it in your code.

Next Topic: Performance Testing


Timing Tests

The execution performance of regular expressions can depend on subtle details. In the worst case, it is possible to construct a regular expressions whose search time grows exponentially with the length of the input string, doubling each time a new character is added. To optimize your expressions Expresso provides two ways to do performance testing.

Single Execution Time Test

Every time you run a match, the execution time of the match is displayed in the status bar underneath the match tree. Unless you have a very slow expression or very long input string, this time is likely to be a small fraction of a second and hence, inaccurate.

Multiple Execution Time Test

For a more accurate time estimate, use the Timing Test command from the Tools menu. You may run many repetitions of the same match (finding all matches), reporting the total time, the average time per repetition, and the time it took to compile the regular expression. If you choose too many repetitions, you can cancel the test and start over again. Note that, since .NET caches all regular expressions, it will not recompile an expression that has been previously compiled during the same invocation of Expresso. Thus, the compilation time is only accurate the first time an expression is run. If you have already run the expression and still want to determine the compilation time, you will need to exit and restart Expresso. Sorry about that!

Next Topic: Register Expresso


How to Register Expresso

Up-to-date information on Expresso, including instructions for obtaining a Registration Code, can be obtained by visiting the Ultrapico web site at:

http://www.ultrapico.com

Registration of Expresso is optional. After a trial period, you will receive reminders to register your copy. Some of the functionality will also be disabled. By registering, you will eliminate these reminders and restore full functionality to Expresso.

To register, send email to eregister@ultrapico.com giving your email address, full name, and saying that you wish to register Expresso. You will receive a User Name and Registration Code by email. To activate your registration, simply select Register from the Help menu and enter the information as shown below. Be sure to enter the User Name and Registration Code exactly as they appear in your email.

Registration is on a per-user basis. Please do not share your registration code with anyone else.

Next Topic: About Expresso


About Expresso

To find information about Expresso, including the version number, licensing and contact information, select the "About Expresso" item in the "Help" menu.

Visit Ultrapico on the Internet at http://www.ultrapico.com or

Send questions or comments to: esupport@ultrapico.com