# 規則運算式中的回溯Backtracking in Regular Expressions

## 不進行回溯的線性比較Linear Comparison Without Backtracking

using System;
using System.Text.RegularExpressions;

public class Example
{
public static void Main()
{
string input = "needing a reed";
string pattern = @"e{2}\w\b";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine("{0} found at position {1}",
match.Value, match.Index);
}
}
// The example displays the following output:
//       eed found at position 11

Imports System.Text.RegularExpressions

Module Example
Public Sub Main()
Dim input As String = "needing a reed"
Dim pattern As String = "e{2}\w\b"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("{0} found at position {1}", _
match.Value, match.Index)
Next
End Sub
End Module
' The example displays the following output:
'       eed found at position 11


11 ee "needing a reed" (索引 0)"needing a reed" (index 0) 沒有符合的結果。No match.
22 ee "eeding a reed" (索引 1)"eeding a reed" (index 1) 可能符合的結果。Possible match.
33 e{2}e{2} "eding a reed" (索引 2)"eding a reed" (index 2) 可能符合的結果。Possible match.
44 \w\w "ding a reed" (索引 3)"ding a reed" (index 3) 可能符合的結果。Possible match.
55 \b\b "ing a reed" (索引 4)"ing a reed" (index 4) 可能符合的結果失敗。Possible match fails.
66 ee "eding a reed" (索引 2)"eding a reed" (index 2) 可能符合的結果。Possible match.
77 e{2}e{2} "ding a reed" (索引 3)"ding a reed" (index 3) 可能符合的結果失敗。Possible match fails.
88 ee "ding a reed" (索引 3)"ding a reed" (index 3) 比對會失敗。Match fails.
99 ee "ing a reed" (索引 4)"ing a reed" (index 4) 沒有符合的結果。No match.
1010 ee "ng a reed" (索引 5)"ng a reed" (index 5) 沒有符合的結果。No match.
1111 ee "g a reed" (索引 6)"g a reed" (index 6) 沒有符合的結果。No match.
1212 ee " a reed" (索引 7)" a reed" (index 7) 沒有符合的結果。No match.
1313 ee "a reed" (索引 8)"a reed" (index 8) 沒有符合的結果。No match.
1414 ee " reed" (索引 9)" reed" (index 9) 沒有符合的結果。No match.
1515 ee "a reed" (索引 10)"reed" (index 10) 沒有符合的結果No match
1616 ee "eed" (索引 11)"eed" (index 11) 可能符合的結果。Possible match.
1717 e{2}e{2} "ed" (索引 12)"ed" (index 12) 可能符合的結果。Possible match.
1818 \w\w "d" (索引 13)"d" (index 13) 可能符合的結果。Possible match.
1919 \b\b "" (索引 14)"" (index 14) 符合的結果。Match.

## 含有選擇性數量詞或交替建構的回溯Backtracking with Optional Quantifiers or Alternation Constructs

using System;
using System.Text.RegularExpressions;

public class Example
{
public static void Main()
{
string input = "Essential services are provided by regular expressions.";
string pattern = ".*(es)";
Match m = Regex.Match(input, pattern, RegexOptions.IgnoreCase);
if (m.Success) {
Console.WriteLine("'{0}' found at position {1}",
m.Value, m.Index);
Console.WriteLine("'es' found at position {0}",
m.Groups[1].Index);
}
}
}
//    'Essential services are provided by regular expres' found at position 0
//    'es' found at position 47

Imports System.Text.RegularExpressions

Module Example
Public Sub Main()
Dim input As String = "Essential services are provided by regular expressions."
Dim pattern As String = ".*(es)"
Dim m As Match = Regex.Match(input, pattern, RegexOptions.IgnoreCase)
If m.Success Then
Console.WriteLine("'{0}' found at position {1}", _
m.Value, m.Index)
Console.WriteLine("'es' found at position {0}", _
m.Groups(1).Index)
End If
End Sub
End Module
'    'Essential services are provided by regular expres' found at position 0
'    'es' found at position 47


• 它會比對 .* (其會比對零個、一個或多個任意字元) 與整個輸入字串。It matches the .* (which matches zero, one, or more occurrences of any character) with the whole input string.

• 它會嘗試比對規則運算式模式中的 "e"。It attempts to match "e" in the regular expression pattern. 不過，輸入字串沒有其他可供比對的字元。However, the input string has no remaining characters available to match.

• 接著它會回溯至上一個成功的比對結果 "Essential services are provided by regular expressions"，並嘗試比對 "e" 與句尾的句號。It backtracks to its last successful match, "Essential services are provided by regular expressions", and attempts to match "e" with the period at the end of the sentence. 比對會失敗。The match fails.

• 然後它會繼續回溯至前一個成功的比對結果，一次一個字元，直到暫時相符的子字串為 "Essential services are provided by regular expr"。It continues to backtrack to a previous successful match one character at a time until the tentatively matched substring is "Essential services are provided by regular expr". 然後運算式會比較模式中的 "e" 與 "expressions" 中的第二個 "e"，並且尋找符合的結果。It then compares the "e" in the pattern to the second "e" in "expressions" and finds a match.

• 接著再比較模式中的 "s" 與相符的 "e" 字元後面接著的 "s" ("expressions" 中的第一個 "s")。It compares "s" in the pattern to the "s" that follows the matched "e" character (the first "s" in "expressions"). 比對將會成功。The match is successful.

## 含有巢狀選擇性數量詞的回溯Backtracking with Nested Optional Quantifiers

using System;
using System.Diagnostics;
using System.Text.RegularExpressions;

public class Example
{
public static void Main()
{
string pattern = "^(a+)+$"; string[] inputs = { "aaaaaa", "aaaaa!" }; Regex rgx = new Regex(pattern); Stopwatch sw; foreach (string input in inputs) { sw = Stopwatch.StartNew(); Match match = rgx.Match(input); sw.Stop(); if (match.Success) Console.WriteLine("Matched {0} in {1}", match.Value, sw.Elapsed); else Console.WriteLine("No match found in {0}", sw.Elapsed); } } }  Imports System.Diagnostics Imports System.Text.RegularExpressions Module Example Public Sub Main() Dim pattern As String = "^(a+)+$"
Dim inputs() As String = { "aaaaaa", "aaaaa!" }
Dim rgx As New Regex(pattern)
Dim sw As Stopwatch

For Each input As String In inputs
sw = Stopwatch.StartNew()
Dim match As Match = rgx.Match(input)
sw.Stop()
If match.Success Then
Console.WriteLine("Matched {0} in {1}", match.Value, sw.Elapsed)
Else
Console.WriteLine("No match found in {0}", sw.Elapsed)
End If
Next
End Sub
End Module


• 它會檢查是否位於字串開頭，然後比對字串中的前五個字元與 a+模式。It checks that it was at the beginning of the string, and then matches the first five characters in the string with the pattern a+. 然後判斷字串中沒有額外的 "a" 字元群組。It then determines that there are no additional groups of "a" characters in the string. 最後測試是否到達字串結尾。Finally, it tests for the end of the string. 由於字串中剩下一個額外的字串，因此比對失敗。Because one additional character remains in the string, the match fails. 這個失敗的比對需要經過 9 次比較。This failed match requires 9 comparisons. 規則運算式引擎還會儲存 "a" (以下稱為符合結果 1)、"aa" (符合結果 2)、"aaa" (符合結果 3) 和 "aaaa" (符合結果 4) 這些符合結果的狀態資訊。The regular expression engine also saves state information from its matches of "a" (which we will call match 1), "aa" (match 2), "aaa" (match 3), and "aaaa" (match 4).

• 它會返回之前儲存的符合結果 4。It returns to the previously saved match 4. 然後判斷出有一個額外的 "a" 字元要指派至額外的擷取群組。It determines that there is one additional "a" character to assign to an additional captured group. 最後測試是否到達字串結尾。Finally, it tests for the end of the string. 由於字串中剩下一個額外的字串，因此比對失敗。Because one additional character remains in the string, the match fails. 這個失敗的比對需要經過 4 次比較。This failed match requires 4 comparisons. 到目前為止，總共執行了 13 次比較。So far, a total of 13 comparisons have been performed.

• 它會返回之前儲存的符合結果 3。It returns to the previously saved match 3. 然後判斷出有兩個額外的 "a" 字元要指派至額外的擷取群組。It determines that there are two additional "a" characters to assign to an additional captured group. 然而，字串結尾測試失敗。However, the end-of-string test fails. 接著它會返回符合結果 3，並嘗試比對兩個額外的擷取群組中的這兩個額外的 "a" 字元。It then returns to match3 and tries to match the two additional "a" characters in two additional captured groups. 字串結尾測試仍然失敗。The end-of-string test still fails. 這些失敗的比對需要經過 12 次比較。These failed matches require 12 comparisons. 到目前為止，總共執行了 25 次比較。So far, a total of 25 comparisons have been performed.

## 控制回溯Controlling Backtracking

### 定義逾時間隔Defining a Time-out Interval

RegexMatchTimeoutException 例外狀況表示規則運算式引擎在指定的逾時間隔內找不到相符項目，但不會指出擲回例外狀況的原因。A RegexMatchTimeoutException exception indicates that the regular expression engine was unable to find a match within the specified time-out interval but does not indicate why the exception was thrown. 這個原因可能是大量回溯，不過也有可能是對於擲回例外狀況當時的系統負載而言，設定的逾時間隔太低。The reason might be excessive backtracking, but it is also possible that the time-out interval was set too low given the system load at the time the exception was thrown. 當您處理例外狀況時，可以選擇中放棄一步比對輸入字串，或增加逾時間隔並重試比對作業。When you handle the exception, you can choose to abandon further matches with the input string or increase the time-out interval and retry the matching operation.

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Security;
using System.Text.RegularExpressions;

public class Example
{
const int MaxTimeoutInSeconds = 3;

public static void Main()
{
string pattern = @"(a+)+$"; // DO NOT REUSE THIS PATTERN. Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase, TimeSpan.FromSeconds(1)); Stopwatch sw = null; string[] inputs= { "aa", "aaaa>", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaa>", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>" }; foreach (var inputValue in inputs) { Console.WriteLine("Processing {0}", inputValue); bool timedOut = false; do { try { sw = Stopwatch.StartNew(); // Display the result. if (rgx.IsMatch(inputValue)) { sw.Stop(); Console.WriteLine(@"Valid: '{0}' ({1:ss\.fffffff} seconds)", inputValue, sw.Elapsed); } else { sw.Stop(); Console.WriteLine(@"'{0}' is not a valid string. ({1:ss\.fffff} seconds)", inputValue, sw.Elapsed); } } catch (RegexMatchTimeoutException e) { sw.Stop(); // Display the elapsed time until the exception. Console.WriteLine(@"Timeout with '{0}' after {1:ss\.fffff}", inputValue, sw.Elapsed); Thread.Sleep(1500); // Pause for 1.5 seconds. // Increase the timeout interval and retry. TimeSpan timeout = e.MatchTimeout.Add(TimeSpan.FromSeconds(1)); if (timeout.TotalSeconds > MaxTimeoutInSeconds) { Console.WriteLine("Maximum timeout interval of {0} seconds exceeded.", MaxTimeoutInSeconds); timedOut = false; } else { Console.WriteLine("Changing the timeout interval to {0}", timeout); rgx = new Regex(pattern, RegexOptions.IgnoreCase, timeout); timedOut = true; } } } while (timedOut); Console.WriteLine(); } } } // The example displays output like the following : // Processing aa // Valid: 'aa' (00.0000779 seconds) // // Processing aaaa> // 'aaaa>' is not a valid string. (00.00005 seconds) // // Processing aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa // Valid: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' (00.0000043 seconds) // // Processing aaaaaaaaaaaaaaaaaaaaaa> // Timeout with 'aaaaaaaaaaaaaaaaaaaaaa>' after 01.00469 // Changing the timeout interval to 00:00:02 // Timeout with 'aaaaaaaaaaaaaaaaaaaaaa>' after 02.01202 // Changing the timeout interval to 00:00:03 // Timeout with 'aaaaaaaaaaaaaaaaaaaaaa>' after 03.01043 // Maximum timeout interval of 3 seconds exceeded. // // Processing aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa> // Timeout with 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>' after 03.01018 // Maximum timeout interval of 3 seconds exceeded.  Imports System.ComponentModel Imports System.Diagnostics Imports System.Security Imports System.Text.RegularExpressions Imports System.Threading Module Example Const MaxTimeoutInSeconds As Integer = 3 Public Sub Main() Dim pattern As String = "(a+)+$"    ' DO NOT REUSE THIS PATTERN.
Dim rgx As New Regex(pattern, RegexOptions.IgnoreCase, TimeSpan.FromSeconds(1))
Dim sw As Stopwatch = Nothing

Dim inputs() As String = { "aa", "aaaa>",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"aaaaaaaaaaaaaaaaaaaaaa>",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>" }

For Each inputValue In inputs
Console.WriteLine("Processing {0}", inputValue)
Dim timedOut As Boolean = False
Do
Try
sw = Stopwatch.StartNew()
' Display the result.
If rgx.IsMatch(inputValue) Then
sw.Stop()
Console.WriteLine("Valid: '{0}' ({1:ss\.fffffff} seconds)",
inputValue, sw.Elapsed)
Else
sw.Stop()
Console.WriteLine("'{0}' is not a valid string. ({1:ss\.fffff} seconds)",
inputValue, sw.Elapsed)
End If
Catch e As RegexMatchTimeoutException
sw.Stop()
' Display the elapsed time until the exception.
Console.WriteLine("Timeout with '{0}' after {1:ss\.fffff}",
inputValue, sw.Elapsed)
Thread.Sleep(1500)       ' Pause for 1.5 seconds.

' Increase the timeout interval and retry.
Dim timeout As TimeSpan = e.MatchTimeout.Add(TimeSpan.FromSeconds(1))
If timeout.TotalSeconds > MaxTimeoutInSeconds Then
Console.WriteLine("Maximum timeout interval of {0} seconds exceeded.",
MaxTimeoutInSeconds)
timedOut = False
Else
Console.WriteLine("Changing the timeout interval to {0}",
timeout)
rgx = New Regex(pattern, RegexOptions.IgnoreCase, timeout)
timedOut = True
End If
End Try
Loop While timedOut
Console.WriteLine()
Next
End Sub
End Module
' The example displays output like the following:
'    Processing aa
'    Valid: 'aa' (00.0000779 seconds)
'
'    Processing aaaa>
'    'aaaa>' is not a valid string. (00.00005 seconds)
'
'    Processing aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
'    Valid: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' (00.0000043 seconds)
'
'    Processing aaaaaaaaaaaaaaaaaaaaaa>
'    Timeout with 'aaaaaaaaaaaaaaaaaaaaaa>' after 01.00469
'    Changing the timeout interval to 00:00:02
'    Timeout with 'aaaaaaaaaaaaaaaaaaaaaa>' after 02.01202
'    Changing the timeout interval to 00:00:03
'    Timeout with 'aaaaaaaaaaaaaaaaaaaaaa>' after 03.01043
'    Maximum timeout interval of 3 seconds exceeded.
'
'    Processing aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>
'    Timeout with 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>' after 03.01018
'    Maximum timeout interval of 3 seconds exceeded.


### 非回溯子運算式Nonbacktracking Subexpression

(?> 子運算式) 語言項目會隱藏子運算式中的回溯。The (?> subexpression) language element suppresses backtracking in a subexpression. 對於避免發生與比對失敗相關的效能問題相當有用。It is useful for preventing the performance problems associated with failed matches.

using System;
using System.Diagnostics;
using System.Text.RegularExpressions;

public class Example
{
public static void Main()
{
bool matched;
Stopwatch sw;

Console.WriteLine("With backtracking:");
string backPattern = "^(([0-9a-fA-F]{1,4}:)*([0-9a-fA-F]{1,4}))*(::)$"; sw = Stopwatch.StartNew(); matched = Regex.IsMatch(input, backPattern); sw.Stop(); Console.WriteLine("Match: {0} in {1}", Regex.IsMatch(input, backPattern), sw.Elapsed); Console.WriteLine(); Console.WriteLine("Without backtracking:"); string noBackPattern = "^((?>[0-9a-fA-F]{1,4}:)*(?>[0-9a-fA-F]{1,4}))*(::)$";
sw = Stopwatch.StartNew();
matched = Regex.IsMatch(input, noBackPattern);
sw.Stop();
Console.WriteLine("Match: {0} in {1}", Regex.IsMatch(input, noBackPattern), sw.Elapsed);
}
}
// The example displays output like the following:
//       With backtracking:
//       Match: False in 00:00:27.4282019
//
//       Without backtracking:
//       Match: False in 00:00:00.0001391

Imports System.Diagnostics
Imports System.Text.RegularExpressions

Module Example
Public Sub Main()
Dim input As String = "b51:4:1DB:9EE1:5:27d60:f44:D4:cd:E:5:0A5:4a:D24:41Ad:"
Dim matched As Boolean
Dim sw As Stopwatch

Console.WriteLine("With backtracking:")
Dim backPattern As String = "^(([0-9a-fA-F]{1,4}:)*([0-9a-fA-F]{1,4}))*(::)$" sw = Stopwatch.StartNew() matched = Regex.IsMatch(input, backPattern) sw.Stop() Console.WriteLine("Match: {0} in {1}", Regex.IsMatch(input, backPattern), sw.Elapsed) Console.WriteLine() Console.WriteLine("Without backtracking:") Dim noBackPattern As String = "^((?>[0-9a-fA-F]{1,4}:)*(?>[0-9a-fA-F]{1,4}))*(::)$"
sw = Stopwatch.StartNew()
matched = Regex.IsMatch(input, noBackPattern)
sw.Stop()
Console.WriteLine("Match: {0} in {1}", Regex.IsMatch(input, noBackPattern), sw.Elapsed)
End Sub
End Module
' The example displays the following output:
'       With backtracking:
'       Match: False in 00:00:27.4282019
'
'       Without backtracking:
'       Match: False in 00:00:00.0001391


### 左合樣判斷提示Lookbehind Assertions

.NET 包含兩個語言元素：(?<=subexpression)(?<!subexpression)，這兩者會比對輸入字串中的前一個或多個字元。.NET includes two language elements, (?<=subexpression) and (?<!subexpression), that match the previous character or characters in the input string. 這兩個語言項目都是零寬度判斷提示，也就是說，它們會判斷緊接著目前字元前面的字元是否可由 子運算式比對，而不需前進或回溯。Both language elements are zero-width assertions; that is, they determine whether the character or characters that immediately precede the current character can be matched by subexpression, without advancing or backtracking.

(?<= 子運算式 ) 是左合樣判斷提示，也就是說，目前位置前面的字元必須符合 子運算式(?<= subexpression ) is a positive lookbehind assertion; that is, the character or characters before the current position must match subexpression. (?<!子運算式) 是左不合樣判斷提示，也就是說，目前位置前面的字元必須不符合 子運算式(?<!subexpression) is a negative lookbehind assertion; that is, the character or characters before the current position must not match subexpression. 子運算式 為前一個子運算式的子集時，左合樣和左不合樣判斷提示最為實用。Both positive and negative lookbehind assertions are most useful when subexpression is a subset of the previous subexpression.

using System;
using System.Diagnostics;
using System.Text.RegularExpressions;

public class Example
{
public static void Main()
{
Stopwatch sw;
string input = "test@contoso.com";
bool result;

string pattern = @"^[0-9A-Z]([-.\w]*[0-9A-Z])?@";
sw = Stopwatch.StartNew();
result = Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase);
sw.Stop();
Console.WriteLine("Match: {0} in {1}", result, sw.Elapsed);

string behindPattern = @"^[0-9A-Z][-.\w]*(?<=[0-9A-Z])@";
sw = Stopwatch.StartNew();
result = Regex.IsMatch(input, behindPattern, RegexOptions.IgnoreCase);
sw.Stop();
Console.WriteLine("Match with Lookbehind: {0} in {1}", result, sw.Elapsed);
}
}
// The example displays output similar to the following:
//       Match: True in 00:00:00.0017549
//       Match with Lookbehind: True in 00:00:00.0000659

Module Example
Public Sub Main()
Dim sw As Stopwatch
Dim input As String = "test@contoso.com"
Dim result As Boolean

Dim pattern As String = "^[0-9A-Z]([-.\w]*[0-9A-Z])?@"
sw = Stopwatch.StartNew()
result = Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase)
sw.Stop()
Console.WriteLine("Match: {0} in {1}", result, sw.Elapsed)

Dim behindPattern As String = "^[0-9A-Z][-.\w]*(?<=[0-9A-Z])@"
sw = Stopwatch.StartNew()
result = Regex.IsMatch(input, behindPattern, RegexOptions.IgnoreCase)
sw.Stop()
Console.WriteLine("Match with Lookbehind: {0} in {1}", result, sw.Elapsed)
End Sub
End Module
' The example displays output similar to the following:
'       Match: True in 00:00:00.0017549
'       Match with Lookbehind: True in 00:00:00.0000659


^ 從字串的開頭開始比對。Start the match at the beginning of the string.
[0-9A-Z] 比對英數字元。Match an alphanumeric character. 這項比較不區分大小寫，因為 Regex.IsMatch 方法是使用 RegexOptions.IgnoreCase 選項呼叫。This comparison is case-insensitive, because the Regex.IsMatch method is called with the RegexOptions.IgnoreCase option.
[-.\w]* 比對出現零次、一次或多次的連字號、句號或文字字元。Match zero, one, or more occurrences of a hyphen, period, or word character.
[0-9A-Z] 比對英數字元。Match an alphanumeric character.
([-.\w]*[0-9A-Z])* 比對出現零次或多次的零個或多個連字號、句號或文字字元組合，後面接著英數字元。Match zero or more occurrences of the combination of zero or more hyphens, periods, or word characters, followed by an alphanumeric character. 這是第一個擷取群組。This is the first capturing group.
@ 比對 "@" 記號。Match an at sign ("@").

^ 從字串的開頭開始比對。Start the match at the beginning of the string.
[0-9A-Z] 比對英數字元。Match an alphanumeric character. 這項比較不區分大小寫，因為 Regex.IsMatch 方法是使用 RegexOptions.IgnoreCase 選項呼叫。This comparison is case-insensitive, because the Regex.IsMatch method is called with the RegexOptions.IgnoreCase option.
[-.\w]* 比對出現零次或多次的連字號、句號或文字字元。Match zero or more occurrences of a hyphen, period, or word character.
(?<=[0-9A-Z]) 如果是英數字，則向左合樣最後一個符合的字元並繼續比對。Look back at the last matched character and continue the match if it is alphanumeric. 請注意，英數字元是由句號、連字號和所有文字字元組成之集合的子集。Note that alphanumeric characters are a subset of the set that consists of periods, hyphens, and all word characters.
@ 比對 "@" 記號。Match an at sign ("@").

.NET 包含兩個語言元素：(?=subexpression)(?!subexpression)，這兩者會比對輸入字串中的下一個或多個字元。.NET includes two language elements, (?=subexpression) and (?!subexpression), that match the next character or characters in the input string. 這兩個語言項目都是零寬度判斷提示，也就是說，它們會判斷緊接著目前字元後面的字元是否可由 子運算式比對，而不需前進或回溯。Both language elements are zero-width assertions; that is, they determine whether the character or characters that immediately follow the current character can be matched by subexpression, without advancing or backtracking.

(?= 子運算式 ) 是右合樣判斷提示，也就是說，目前位置後面的字元必須符合 子運算式(?= subexpression ) is a positive lookahead assertion; that is, the character or characters after the current position must match subexpression. (?!子運算式) 是右不合樣判斷提示，也就是說，目前位置後面的字元必須不符合 子運算式(?!subexpression) is a negative lookahead assertion; that is, the character or characters after the current position must not match subexpression. 子運算式 為下一個子運算式的子集時，右合樣和右不合樣判斷提示最為實用。Both positive and negative lookahead assertions are most useful when subexpression is a subset of the next subexpression.

using System;
using System.Diagnostics;
using System.Text.RegularExpressions;

public class Example
{
public static void Main()
{
string input = "aaaaaaaaaaaaaaaaaaaaaa.";
bool result;
Stopwatch sw;

string pattern = @"^(([A-Z]\w*)+\.)*[A-Z]\w*$"; sw = Stopwatch.StartNew(); result = Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase); sw.Stop(); Console.WriteLine("{0} in {1}", result, sw.Elapsed); string aheadPattern = @"^((?=[A-Z])\w+\.)*[A-Z]\w*$";
sw = Stopwatch.StartNew();
sw.Stop();
Console.WriteLine("{0} in {1}", result, sw.Elapsed);
}
}
// The example displays the following output:
//       False in 00:00:03.8003793
//       False in 00:00:00.0000866

Imports System.Diagnostics
Imports System.Text.RegularExpressions

Module Example
Public Sub Main()
Dim input As String = "aaaaaaaaaaaaaaaaaaaaaa."
Dim result As Boolean
Dim sw As Stopwatch

Dim pattern As String = "^(([A-Z]\w*)+\.)*[A-Z]\w*$" sw = Stopwatch.StartNew() result = Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase) sw.Stop() Console.WriteLine("{0} in {1}", result, sw.Elapsed) Dim aheadPattern As String = "^((?=[A-Z])\w+\.)*[A-Z]\w*$"
sw = Stopwatch.StartNew()
sw.Stop()
Console.WriteLine("{0} in {1}", result, sw.Elapsed)
End Sub
End Module
' The example displays the following output:
'       False in 00:00:03.8003793
'       False in 00:00:00.0000866


^ 從字串的開頭開始比對。Start the match at the beginning of the string.
([A-Z]\w*)+\. 比對後面接著零個或多個文字字元的字母字元 (A-Z) 一次或多次，後面接著句號。Match an alphabetical character (A-Z) followed by zero or more word characters one or more times, followed by a period. 這項比較不區分大小寫，因為 Regex.IsMatch 方法是使用 RegexOptions.IgnoreCase 選項呼叫。This comparison is case-insensitive, because the Regex.IsMatch method is called with the RegexOptions.IgnoreCase option.
(([A-Z]\w*)+\.)* 比對上一個模式零次或多次。Match the previous pattern zero or more times.
[A-Z]\w* 比對後面接著零個或多個文字字元的字母字元。Match an alphabetical character followed by zero or more word characters.
$ 在輸入字串結尾結束比對。End the match at the end of the input string. 第二個規則運算式模式 ^((?=[A-Z])\w+\.)*[A-Z]\w*$使用右合樣判斷提示。The second regular expression pattern, ^((?=[A-Z])\w+\.)*[A-Z]\w*$, uses a positive lookahead assertion. 其定義方式如下表所示。It is defined as shown in the following table. 模式Pattern 說明Description ^ 從字串的開頭開始比對。Start the match at the beginning of the string. (?=[A-Z]) 如果是字母 (A-Z)，則向右合樣至第一個字元並繼續比對。Look ahead to the first character and continue the match if it is alphabetical (A-Z). 這項比較不區分大小寫，因為 Regex.IsMatch 方法是使用 RegexOptions.IgnoreCase 選項呼叫。This comparison is case-insensitive, because the Regex.IsMatch method is called with the RegexOptions.IgnoreCase option. \w+\. 比對後面接著句號的零個或多個文字字元。Match one or more word characters followed by a period. ((?=[A-Z])\w+\.)* 比對後面接句號的一個或多個文字字元這個模式一次或多次。Match the pattern of one or more word characters followed by a period zero or more times. 初始文字字元必須是字母。The initial word character must be alphabetical. [A-Z]\w* 比對後面接著零個或多個文字字元的字母字元。Match an alphabetical character followed by zero or more word characters. $ 在輸入字串結尾結束比對。End the match at the end of the input string.