Some more words about Regular Expressions





Here I am trying to clarify a little bit more what regular expressions are. I do hope it will help you. Please don't hesitate contacting me if you have further questions.
 

1.


Regular expressions are key concepts in Unix. Basically you can find them in two major fields: wildcards under shell (like ls a* or rm d?.tmp), and as searching patterns for grep, sed, Perl, etc.

The main idea is that a regular expression describes a set of strings (a set of character sequences). Or, if you prefer, a regular expression describes some property, and some strings will match this property (so they will be the element of the set), while others won't.

For instance, the d?.tmp describes the following set of character strings when appearing as the argument of a Unix command:
 

{da.tmp, db.tmp, ..., dz.tmp, d0.tmp, d1.tmp, ... , d9.tmp, d$.tmp, d?.tmp, d+.tmp, d(.tmp, ...}


Putting that into words: any string beginning with the character 'd', followed by one character (that can be any possible character), and followed by the substring '.tmp'. If you want, this is the property which characterizes the elements of the above set: all strings that match this property, will be elements of the set, but all strings that do not match this property will be out of the above set.

Another example: under grep, the expression ' [a-z]..x' describes any string that begins with a character within the range 'a' to 'z', followed by two characters (that can be letters, numbers, punctuation marks, etc.), and ending with the character 'x'. If you want, the regular expression describes this set of strings. Or, if you prefer, the regular expression describes this property (of "beginning with ..., ending with..."). The point is that it can be always decided whether a string matches this property (is the element of the set), or not.

Generally speaking, a regular expression is a formalism to describe a set of character strings. Or, if you prefer: a regular expression describes a pattern / a property , and the set corresponding to the regular expression is the set of strings that match this pattern.
 

2.


The details of the formalism and its purpose of using can be very different. For instance:

 - In shell, if you use wildcards in the argument of a commands (e.g. ls a* or rm d?.tmp), then the preprocessor of the shell will replace the expression with all filenames that match this expression (that belong to the set described by the expression). All this applies only if there is at least one filename (in the current directory, or in the referred directory, -ies) that would match the expression, otherwise the wildcards are understood as being regular characters. Furthermore, all this is done before the actual command is run (in a preprocessing stage), therefore this replacement is executed independently from the command itself (whether it would look for filenames as arguments or not).

 - In grep: the command would return all lines of the input that have a substring that matches the regular expression (a sequence within the line that is an element of the set described by the regular expression).

 - In sed, the command /RegExp/d will delete all lines of the input string that have a substring that matches the regular expression. The command s/RegExp/String/ will change in each line the (first) substring that matches RegExp into String.

 - In Perl the expression String =~ RegExp is true if and only if String has a substring that matches RegExp. (!~ is its negation.)

You can see that both in grep, sed and Perl, the regular expressions describe a pattern, and the question is always whether it is possible to find such a substring within some longer strings. This longer string is a line within a file in the first two cases, and it is the value of some variables or the value of some expressions in the third one.
 

3.


So now the question is what tools you have in order to describe the patterns that you want to be matched  by filenames or by substrings? In other words: what tools do you have in order to describe this set of strings?

In fact, this question is part of a much larger field that is called "formal language theory". It is a subfield of mathematics (of algebra), and it was developed in the last 50-60 years in order to meet the needs of computational science and modern linguistics. (Therefore you will have a special course on formal languages during your studies at Alfa-Informatica.) The starting point of formal language theory is the following: you have an alphabet (e.g. a-z, A-Z, 0-9, punctuation marks, etc.), and using this alphabet you can write down all kinds of words. A language is a set of words written down using this alphabet.

Let us consider the following language: {a, ab, aba, abab, ababa, ababab, abababa,...}. Now let's try to describe that language. How would you do that? The rule is the following: a word must begin with the character 'a', and then a 'b' must be preceeded by an 'a', and an 'a' (except of the first one) must be preceeded by a 'b'. So the word 'abababababababababa' is an element of this language, because it follows the rule. But 'babababab' is not an element of this language, because its first character is not an 'a' (this was the first part of our rule). And 'abaababbaabbaba' is not an element of this language either, because the second part of the rule is not satisfied.

The goal of formal language theory is to invent different sets of formal tools with which you can describe such a language; and then to investigate the following question: what kind of tools can describe what kind of languages?

In the case of regular expressions for example, we have the following four basic tools:

Then you can have additional tools, for instance:
 


For instance, how would we formalize the above rule, describing the language {a, ab, aba, abab, ababa,..}, using the tools of regular expressions? Well, let us reformulate our rule. The string should start with a character 'a', then you can have any number of the bi-gram 'ba' (zero or more times), followed by an optional 'b'. Try it out, this rule will describe exactly the above language. So now we can formulate this set in a formal way, using the tools of regular expressions (using the notations of grep, sed or Perl):
 

a(ba)*b?


A further remark: since grep, sed and Perl usually use regular expressions for looking for a pattern within a string, you sometimes want to refer to the place of this pattern within the bigger string. For instance you want your pattern to occur at the beginning of your larger string (e.g. at the beginning of the line in the case of grep and sed). Therefore you can use the ^ character that reads "beginning of the line / beginning of the string", so the RegExp ^[aeiou][0-9] means: 'at the beginning of the line, you want first a vowel, then a digit'. The same applies to the $ symbol, meaning 'end of the string / end of the line'.

By the way, this helps you in formulating queries when you don't want just part of your string / part of your line to match a certain regular expression, but you want instead the whole string / the whole line to match your regular expression. So ^RegExp$ means, that the regular expression covers exactly the string / the line, because on the left it must hit the beginning, and on the right end it must hit the end of the string / of the line.
 

4.


Finally, let me give you the mathematical definition of a regular expression:
 

Definition: Let S be your alpahabet. Then the set of regular expressions with respect to the set S meets the following criteria:

 (i) The empty string is a regular expression and the set {a} for any element a of S is a regular expression.

 (ii) If P and Q are regular expressions, then
     - their concatenation P.Q is also a regular expression;
     - their union P U Q is also a regular expression;
     - the Kleene-star of P, i.e. P* is also a regular expression.

 (iii) There are no other regular expressions.
 

Finally, let me mention that regular expressions are closely related to the so-called Finite State Automata and to Regular Grammars, and the set of languages that can be described by all of these tools are called regular languages. The Alfa Informatica Department is proud of being one of the most important centers in the world in implementing these mathematical tools for linguistic models. Here is the Finite State web-site of Jan Daciuk, and here is the web page of FSA Utilities developped by Gertjan van Noord.