Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Beginning Regular Expressions 2005.pdf
Скачиваний:
95
Добавлен:
17.08.2013
Размер:
25.42 Mб
Скачать

Lookahead and Lookbehind

When the regular expression is modified to (Andrew)(s)(?=\b), you capture the character sequence Andrew in $1 and capture the s in $2. The lookahead does not capture any characters. So to insert an apostrophe, you want $1 (Andrew) to be followed by an apostrophe to be followed by $2 (a lowercase s).

Lookbehind

Lookbehind tests whether a sequence of characters that is matched is preceded (positive lookbehind) or not preceded (negative lookbehind) by another sequence of characters.

For example, if you wanted to match the surname Jekyll only if it is preceded by the sequence of characters Dr. (an uppercase D, a lowercase r, a period, and a space character), you would use a pattern like this:

(?<=Dr. )Jekyll

The component (?<=Dr. ) indicates the sequence of characters that is tested for as a lookbehind, and the component Jekyll matches literally.

Positive Lookbehind

A positive lookbehind is a constraint on matching. Matching occurs only if the pattern to be matched is preceded by the pattern contained in the lookbehind assertion.

Try It Out

Positive Lookbehind

1.Open the Komodo Regular Expression Toolkit, and delete any residual regular expression and sample text.

2.In the Enter a String to Match Against area, enter the test text, Mr. Hyde and Dr. Jekyll are characters in a famous novel.

3.In the Enter a Regular Expression area, enter the pattern (?<=Dr. )Jekyll.

4.Inspect the highlighted text in the String to Match Against area and the description of the results in the gray area below, Match succeeded: 0 groups.

Figure 8-9 shows the appearance. Notice that the sequence of characters Jekyll is highlighted.

5.Edit the regular expression pattern to read (?<=Mr. )Jekyll.

6.Inspect the description of the results in the gray area, No matches found.

7.Edit the regular expression pattern to read ((?<=Mr. )|(?<=Mister ))Hyde. Ensure that there is a space character after the r of Mister. If that is omitted, there will be no match.

209

Chapter 8

Figure 8-9

8.Inspect the description of the results in the gray area, Match succeeded: 1 group. Also notice that the character sequence Hyde is highlighted.

9.Edit the Mr. in the test text to read Mister.

10.Inspect the gray area again. Again, the description is Match succeeded: 1 group. Figure 8-10 shows the appearance.

Figure 8-10

210

Lookahead and Lookbehind

How It Works

The following description of how the regular expression engine operates is a conceptual one and may not reflect the approach taken by any individual regular expression engine. The text matched is the sequence of characters Jekyll.

Matching starts at the beginning of the test text. The character following the regular expression’s position is checked to see whether it is an uppercase J. If so, that is matched, and an attempt is made to match the other characters making up the sequence of characters Jekyll. If any attempt to match fails, the whole pattern fails, and the regular expression engine moves forward through the text attempting to match the character sequence Jekyll.

If a match is found for the character sequence Jekyll, the regular expression engine is at the position immediately before the J of Jekyll. It checks that the immediately preceding character is a space character. If so, it then tests if the character before that is a period character. If so, it tests if the character before that is a lowercase r. Finally, it tests if the character before that is an uppercase D. Because matching of Jekyll was successful, and the constraint that the character sequence Jekyll be preceded by the character sequence Dr. (including a space character) was satisfied, the whole regular expression succeeds.

When you edit the pattern to read (?<=Mr. )Jekyll, the character sequence Jekyll is successfully matched as before. However, when the regular expression engine checks the characters that precede that character sequence, the constraint fails, because despite the fact (reading backward) that the space character, the period character, and the lowercase r are all present, there is no preceding uppercase D. Because the lookbehind constraint is not satisfied, there is no match.

It is possible to express alternatives in lookbehind. The problem definition might read as follows:

Match the character sequence Hyde if it is preceded by EITHER the character sequence Mr. (including a final space character) OR by the character sequence Mister (including a final space character).

After changing the pattern to read ((?<=Mr. )|(?<=Mister ))Hyde, the regular expression engine attempts to match the character sequence Hyde. When it reaches the position immediately before the H of Hyde it will successfully match that character sequence. It then must also satisfy the constraint on the sequence of characters that precedes Hyde.

The pattern ((?<=Mr. )|(?<=Mister ))Hyde uses parentheses to group two alternative patterns that must precede Hyde. The first option, specified by the pattern (?<=Mr. ), requires that the sequence of four characters M, r, a period, and a space character must precede Hyde. At Step 8, that four-character sequence matches.

After the edit has been made to the test text, replacing Mr. with Mister, the other alternative comes into play. The pattern (?<=Mister ) requires that a seven-character sequence (Mister plus a space character) precedes Hyde.

The positioning of the lookbehind assertion is important, as you will see in the next example.

211

Chapter 8

Try It Out

Positioning of Positive Lookbehind

1.Open RegexBuddy, click the Match tab, and enter the regular expression (?<=like )SQL Server.

2.Click the Test tab, click the Open File icon, and open the Databases.txt file.

3.Click the Find First icon, and inspect the highlighted text in the pane in the Test tab, as shown in Figure 8-11.

Figure 8-11

4.Edit the regular expression in the Match tab so that it reads SQL Server(?<=like ).

5.Click the Find First icon in the Test tab. Confirm that there is no now no highlighted text.

6.Edit the regular expression in the Match tab so that it reads SQL Server(?<=like SQL Server).

7.Click the Find First icon in the Test tab. Confirm that there is again a match in the test text, as shown in Figure 8-12.

How It Works

When the pattern is (?<=like )SQL Server, the lookbehind looks behind, starting from the position immediately before the S of SQL. Because the character sequence like SQL Server exists in the test text, there is a match. When the pattern is SQL Server(?<=like ), the lookbehind starts from the position after the r of Server. Because that position is preceded by Server, not like, and the lookbehind is attempting to match the character sequence like, there is no match.

212