Doporučené postupy pro regulární výrazy v.NET Framework
Regulární výraz motoru.NET Framework je výkonný a všestranný nástroj, který zpracuje na základě porovnávací, nikoli na shodu Doslovný text a porovnávání textu. Ve většině případů provádí porovnávání rychle a efektivně. V některých případech však může motor regulární výraz zobrazí velmi pomalé. V extrémních případech může dokonce zobrazit přestane reagovat během hodiny nebo i dny zpracování relativně malé vstupní v průběhu.
Toto téma popisuje některé doporučené postupy, které vývojáři mohou přijmout k zajištění, že jejich regulární výrazy dosáhnout optimální výkon. Obsahuje následující části:
Zvažte vstupní zdroj
Vytvoření instance objektu vhodně zpracovat
Převzetí Backtracking
Sběr pouze v případě potřeby
Příbuzná témata
Zvažte vstupní zdroj
Regulární výrazy můžete přijmout obecně dva druhy vstup: omezený nebo unconstrained. Vynucené vstup je text, který pochází ze známé nebo spolehlivé zdroje a sleduje předdefinovaného formátu. Vstup bez omezení je text, který pochází z nedůvěryhodného zdroje, jako webový uživatel a nikoli podle předdefinované nebo očekávaný formát.
Odpovídají platné vstupní vzorců regulárních výrazů jsou obvykle zapsány. Text a potom zápis vzorce regulárního výrazu, který odpovídá jej chtějí zkoumat, vývojáři. Vývojáři poté zjistit, zda tento vzorek vyžaduje opravu nebo další rozpracování testováním s více položkami platné vstupní. Vzorek odpovídá předpokládané všechny platné vstupy, je deklarován jako výrobní připraven a může být součástí vydané aplikací. Díky regulárního výrazu vhodný pro odpovídající vynucené vstup. Však ji jako je vhodný pro odpovídající vstup bez omezení.
Regulární výraz odpovídá vstup bez omezení, musí být účinně zpracovat tři druhy textu:
Text, který odpovídá vzorce regulárního výrazu.
Text, který neodpovídá vzorce regulárního výrazu.
Text, který odpovídá téměř vzorce regulárního výrazu.
Poslední typ text je problematická zejména pro regulární výraz vzniku zpracovávat vstupní omezené. Pokud tento regulární výraz závisí také na rozsáhlé backtracking, motor regulárního výrazu můžete strávit neúměrné množství času (v některých případech mnoho hodin nebo dní) zpracování textu zdánlivě nepatrná.
Zvažte například velmi problematické, ale velmi často používané regulární výraz pro ověření aliasu e-mailovou adresu. Regulární výraz ^[0-9A-Z]([-.\w]*[0-9A-Z])*$ je zapsán zpracovat co se považuje za, zdůrazňuje platnou e-mailovou adresu, který je tvořen alfanumerickým znakem nebo podtržítkem následovaným nula nebo více znaků, které mohou být alfanumerické, období, nebo pomlčky. Regulární výraz musí končit alfanumerickým znakem nebo podtržítkem. Následující příklad ukazuje, přestože tento regulární výraz zpracovává platné vstupní snadno, jeho výkon je však velmi neefektivní při zpracovává téměř platné vstupní.
Imports System.Diagnostics
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim sw As Stopwatch
Dim addresses() As String = { "AAAAAAAAAAA@anyco.com",
"AAAAAAAAAAaaaaaaaaaa!@anyco.com" }
Dim pattern As String = "^[0-9A-Z]([-.\w]*[0-9A-Z])*$"
Dim input As String
For Each address In addresses
Dim mailBox As String = address.Substring(0, address.IndexOf("@"))
Dim index As Integer = 0
For ctr As Integer = mailBox.Length - 1 To 0 Step -1
index += 1
input = mailBox.Substring(ctr, index)
sw = Stopwatch.StartNew()
Dim m As Match = Regex.Match(input, pattern, RegexOptions.IgnoreCase)
sw.Stop()
if m.Success Then
Console.WriteLine("{0,2}. Matched '{1,25}' in {2}",
index, m.Value, sw.Elapsed)
Else
Console.WriteLine("{0,2}. Failed '{1,25}' in {2}",
index, input, sw.Elapsed)
End If
Next
Console.WriteLine()
Next
End Sub
End Module
' The example displays output similar to the following:
' 1. Matched ' A' in 00:00:00.0007122
' 2. Matched ' AA' in 00:00:00.0000282
' 3. Matched ' AAA' in 00:00:00.0000042
' 4. Matched ' AAAA' in 00:00:00.0000038
' 5. Matched ' AAAAA' in 00:00:00.0000042
' 6. Matched ' AAAAAA' in 00:00:00.0000042
' 7. Matched ' AAAAAAA' in 00:00:00.0000042
' 8. Matched ' AAAAAAAA' in 00:00:00.0000087
' 9. Matched ' AAAAAAAAA' in 00:00:00.0000045
' 10. Matched ' AAAAAAAAAA' in 00:00:00.0000045
' 11. Matched ' AAAAAAAAAAA' in 00:00:00.0000045
'
' 1. Failed ' !' in 00:00:00.0000447
' 2. Failed ' a!' in 00:00:00.0000071
' 3. Failed ' aa!' in 00:00:00.0000071
' 4. Failed ' aaa!' in 00:00:00.0000061
' 5. Failed ' aaaa!' in 00:00:00.0000081
' 6. Failed ' aaaaa!' in 00:00:00.0000126
' 7. Failed ' aaaaaa!' in 00:00:00.0000359
' 8. Failed ' aaaaaaa!' in 00:00:00.0000414
' 9. Failed ' aaaaaaaa!' in 00:00:00.0000758
' 10. Failed ' aaaaaaaaa!' in 00:00:00.0001462
' 11. Failed ' aaaaaaaaaa!' in 00:00:00.0002885
' 12. Failed ' Aaaaaaaaaaa!' in 00:00:00.0005780
' 13. Failed ' AAaaaaaaaaaa!' in 00:00:00.0011628
' 14. Failed ' AAAaaaaaaaaaa!' in 00:00:00.0022851
' 15. Failed ' AAAAaaaaaaaaaa!' in 00:00:00.0045864
' 16. Failed ' AAAAAaaaaaaaaaa!' in 00:00:00.0093168
' 17. Failed ' AAAAAAaaaaaaaaaa!' in 00:00:00.0185993
' 18. Failed ' AAAAAAAaaaaaaaaaa!' in 00:00:00.0366723
' 19. Failed ' AAAAAAAAaaaaaaaaaa!' in 00:00:00.1370108
' 20. Failed ' AAAAAAAAAaaaaaaaaaa!' in 00:00:00.1553966
' 21. Failed ' AAAAAAAAAAaaaaaaaaaa!' in 00:00:00.3223372
using System;
using System.Diagnostics;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
Stopwatch sw;
string[] addresses = { "AAAAAAAAAAA@anyco.com",
"AAAAAAAAAAaaaaaaaaaa!@anyco.com" };
string pattern = @"^[0-9A-Z]([-.\w]*[0-9A-Z])*$";
string input;
foreach (var address in addresses) {
string mailBox = address.Substring(0, address.IndexOf("@"));
int index = 0;
for (int ctr = mailBox.Length - 1; ctr >= 0; ctr--) {
index++;
input = mailBox.Substring(ctr, index);
sw = Stopwatch.StartNew();
Match m = Regex.Match(input, pattern, RegexOptions.IgnoreCase);
sw.Stop();
if (m.Success)
Console.WriteLine("{0,2}. Matched '{1,25}' in {2}",
index, m.Value, sw.Elapsed);
else
Console.WriteLine("{0,2}. Failed '{1,25}' in {2}",
index, input, sw.Elapsed);
}
Console.WriteLine();
}
}
}
// The example displays output similar to the following:
// 1. Matched ' A' in 00:00:00.0007122
// 2. Matched ' AA' in 00:00:00.0000282
// 3. Matched ' AAA' in 00:00:00.0000042
// 4. Matched ' AAAA' in 00:00:00.0000038
// 5. Matched ' AAAAA' in 00:00:00.0000042
// 6. Matched ' AAAAAA' in 00:00:00.0000042
// 7. Matched ' AAAAAAA' in 00:00:00.0000042
// 8. Matched ' AAAAAAAA' in 00:00:00.0000087
// 9. Matched ' AAAAAAAAA' in 00:00:00.0000045
// 10. Matched ' AAAAAAAAAA' in 00:00:00.0000045
// 11. Matched ' AAAAAAAAAAA' in 00:00:00.0000045
//
// 1. Failed ' !' in 00:00:00.0000447
// 2. Failed ' a!' in 00:00:00.0000071
// 3. Failed ' aa!' in 00:00:00.0000071
// 4. Failed ' aaa!' in 00:00:00.0000061
// 5. Failed ' aaaa!' in 00:00:00.0000081
// 6. Failed ' aaaaa!' in 00:00:00.0000126
// 7. Failed ' aaaaaa!' in 00:00:00.0000359
// 8. Failed ' aaaaaaa!' in 00:00:00.0000414
// 9. Failed ' aaaaaaaa!' in 00:00:00.0000758
// 10. Failed ' aaaaaaaaa!' in 00:00:00.0001462
// 11. Failed ' aaaaaaaaaa!' in 00:00:00.0002885
// 12. Failed ' Aaaaaaaaaaa!' in 00:00:00.0005780
// 13. Failed ' AAaaaaaaaaaa!' in 00:00:00.0011628
// 14. Failed ' AAAaaaaaaaaaa!' in 00:00:00.0022851
// 15. Failed ' AAAAaaaaaaaaaa!' in 00:00:00.0045864
// 16. Failed ' AAAAAaaaaaaaaaa!' in 00:00:00.0093168
// 17. Failed ' AAAAAAaaaaaaaaaa!' in 00:00:00.0185993
// 18. Failed ' AAAAAAAaaaaaaaaaa!' in 00:00:00.0366723
// 19. Failed ' AAAAAAAAaaaaaaaaaa!' in 00:00:00.1370108
// 20. Failed ' AAAAAAAAAaaaaaaaaaa!' in 00:00:00.1553966
// 21. Failed ' AAAAAAAAAAaaaaaaaaaa!' in 00:00:00.3223372
Výstup z příkladu ukazuje, zpracovává stroj regulární výraz platný e-mail alias v o stejný časový interval, bez ohledu na jeho délku. Na druhé straně při téměř platnou e-mailovou adresu má více než pět znaků, doba zpracování přibližně zdvojnásobuje pro každý další znak v řetězci. To znamená, že téměř platný řetězec znaků 28 trvat přes hodinu zpracování a téměř platný řetězec znaků 33 by trvat téměř denně zpracovat.
Protože tento regulární výraz byl vyvinut výhradně formát vstupního odpovídal zvažování, se nezdaří s ohledem na vstup, který neodpovídá vzorku. To zase povolit vstup bez omezení, který téměř odpovídá vzorku regulárního výrazu výrazně snížit výkon.
Chcete-li tento problém vyřešit, proveďte následující:
Při vývoji vzorek zvažte jak backtracking může ovlivnit výkon motoru regulárního výrazu, zejména pokud regulární výraz je určen ke zpracování bez omezení vstupu. Další informace naleznete Vzít poplatek z Backtracking oddílu.
Regulární výraz pomocí poblíž platné a neplatné vstupní platné vstupní důkladně otestujte. Náhodně vygenerovat vstupní zejména regulárního výrazu, můžete použít Rex, což je nástroj průzkum regulárního výrazu z výzkumu společnosti Microsoft.
Vytvoření instance objektu vhodně zpracovat
Srdcem.Objektový model .NET Framework regulární výraz je System.Text.RegularExpressions.Regex třídy, která představuje motor regulárního výrazu. Jediné co největší faktor, který ovlivňuje výkon regulární výraz je často způsobem Regex modul použit. Definování regulární výraz zahrnuje pevně spojovacího zařízení motoru regulární výraz s regulárního výrazu. Že spojovacího procesu, zda zahrnuje konkretizaci Regex objekt regulárního výrazu předáním jeho konstruktoru nebo předáním spolu s řetězcem analyzovaný vzorek regulární výraz volá statickou metodu, je nutnost drahé jeden.
Poznámka |
---|
Podrobnější informace o výkonu důsledky používání regulárních výrazů interpretovaný a kompilované viz Optimalizace výkonu regulární výraz, část II: Převzetí Backtracking v blogu BCL týmu. |
Můžete spojit s konkrétní regulárního výrazu motoru regulární výraz a potom pomocí motoru odpovídající text několika způsoby:
Statické metody porovnávání mohou volat jako Regex.Match(String, String). Nevyžaduje vytvoření instance objektu regulárního výrazu.
Můžete konkretizovat Regex objektu a volat metodu porovnávání instance interpretovaný regulární výraz. Toto je výchozí metodu vazby motoru regulární výraz regulárního výrazu. Vyplývá při Regex je vytvořena instance objektu bez options argument, který zahrnuje Compiled příznak.
Můžete konkretizovat Regex objektu a volat metodu porovnávání instance kompilované regulární výraz. Regulární výraz objekty představují kompilovaný vzorků při Regex vytvořena instance objektu s options argument, který zahrnuje Compiled příznak.
Můžete vytvořit zvláštní účel Regex objektu pevně s vzorkem zejména regulárního výrazu, zkompilujte a uložte do samostatných sestavení. Provést voláním Regex.CompileToAssembly metody.
Zejména způsobem, ve kterém volání metody porovnávání regulárního výrazu může mít významný dopad na aplikaci. Následující oddíly popisují při použití statické metody volá interpretovány regulární výrazy a kompilován regulární výrazy pro zvýšení výkonu aplikace.
Důležité |
---|
Formulář metody volání (statické, interpretovaný, sestavený) ovlivňuje výkon opakovaně používá stejné regulární výraz ve volání metody nebo aplikace využívá objekty regulárního výrazu. |
Statické regulární výrazy
Regulární výraz statické metody jsou doporučovány jako alternativu k opakovaně konkretizaci objekt regulárního výrazu stejným regulární výraz. Na rozdíl od vzorců regulárních výrazů, které používají objekty regulárního výrazu kódy operace nebo zkompilovaný Microsoft zprostředkující jazyk (MSIL) ze vzorků použitých volání metody instance ukryto interně strojem regulárního výrazu.
Například obslužnou rutinu události zavolá často jinou metodu ověření vstupu uživatele. To se odráží v následujícím kódu, ve kterém Button ovládacího prvku Click událostí lze volat metodu pojmenovanou IsValidCurrency, který zkontroluje, zda uživatel zadal symbol měny, následované alespoň jeden desítkové číslice.
Public Sub OKButton_Click(sender As Object, e As EventArgs) _
Handles OKButton.Click
If Not String.IsNullOrEmpty(sourceCurrency.Text) Then
If RegexLib.IsValidCurrency(sourceCurrency.Text) Then
PerformConversion()
Else
status.Text = "The source currency value is invalid."
End If
End If
End Sub
public void OKButton_Click(object sender, EventArgs e)
{
if (! String.IsNullOrEmpty(sourceCurrency.Text))
if (RegexLib.IsValidCurrency(sourceCurrency.Text))
PerformConversion();
else
status.Text = "The source currency value is invalid.";
}
Velmi neefektivní provádění IsValidCurrency Metoda je znázorněn v následujícím příkladu. Všimněte si, že každé volání metody reinstantiates Regex objekt se stejným vzorkem. To zase znamená provedena nová že vzorce regulárního výrazu musí být kompilace pokaždé, když je zavolána metoda.
Imports System.Text.RegularExpressions
Public Module RegexLib
Public Function IsValidCurrency(currencyValue As String) As Boolean
Dim pattern As String = "\p{Sc}+\s*\d+"
Dim currencyRegex As New Regex(pattern)
Return currencyRegex.IsMatch(currencyValue)
End Function
End Module
using System;
using System.Text.RegularExpressions;
public class RegexLib
{
public static bool IsValidCurrency(string currencyValue)
{
string pattern = @"\p{Sc}+\s*\d+";
Regex currencyRegex = new Regex(pattern);
return currencyRegex.IsMatch(currencyValue);
}
}
Tento kód neefektivní měla nahradit volání ke statickému Regex.IsMatch(String, String) metody. To eliminuje nutnost vytvořit instance Regex objekt pokaždé, když chcete volat metodu porovnávání a umožňuje stroj regulární výraz načtení kompilované verze regulární výraz ze své mezipaměti.
Imports System.Text.RegularExpressions
Public Module RegexLib
Public Function IsValidCurrency(currencyValue As String) As Boolean
Dim pattern As String = "\p{Sc}+\s*\d+"
Return Regex.IsMatch(currencyValue, pattern)
End Function
End Module
using System;
using System.Text.RegularExpressions;
public class RegexLib
{
public static bool IsValidCurrency(string currencyValue)
{
string pattern = @"\p{Sc}+\s*\d+";
return Regex.IsMatch(currencyValue, pattern);
}
}
Standardně poslední 15 naposledy použitých vzorky jsou uloženy do mezipaměti statické regulárnímu výrazu. Pro aplikace vyžadující větší počet mezipaměti statické regulární výrazy, lze upravit nastavením velikost mezipaměti Regex.CacheSize vlastnost.
Regulární výraz \p{Sc}+\s*\d+ používané v tomto příkladu ověří vstupní řetězec se skládá z symbol měny a alespoň jeden desítkové číslice. Vzorek je definován podle následující tabulky.
Maska |
Popis |
---|---|
\p{Sc}+ |
Jeden nebo více znaků v Unicode Symbol měny kategorie odpovídají. |
\s* |
Porovná žádný nebo více prázdných znaků. |
\d+ |
Porovná jednu nebo více desítkových číslic. |
Interpretovaný vs.Kompilované regulární výrazy
Regulární výraz vzorky, které jsou vázány na motoru prostřednictvím Specifikace regulárního výrazu Compiled možnost interpretovány. Po konkretizaci objekt regulárního výrazu převede motoru regulární výraz sadu kódů operace regulárního výrazu. Při volání metody instance jsou převedeny do MSIL a provedeny kompilátor JIT kódy operace. Podobně je volána metoda statická regulární výraz a regulární výraz nebyl nalezen v mezipaměti, motor regulární výraz regulárního výrazu převede na sadu kódů operace a ukládá do mezipaměti. Potom převede tyto kódy operace na MSIL takže kompilátor JIT je možné provést. Interpretovaný regulární výrazy zkrátit dobu spouštění na druhou stranu pomalejší doba provádění. Z tohoto důvodu jsou používány nejlepší regulární výraz je používán pro malý počet volání metody nebo přesný počet volání metod regulárního výrazu není známa, ale je očekáváno malé. Jako počet metoda volání zvyšuje výkon zisk ze snížené spuštění je outstripped podle pomalejší rychlost vykonávání.
Regulární výraz vzorky, které jsou vázány na motoru prostřednictvím Specifikace regulárního výrazu Compiled možnost jsou kompilovány. To znamená, že konkretizaci objekt regulárního výrazu nebo kdy je volána metoda statická regulární výraz a regulární výraz nebyl nalezen v mezipaměti, motoru regulárního výrazu převede regulární výraz na zprostředkující sadu kódů operace, které pak převede MSIL. Když je zavolána metoda, provede kompilátor JIT MSIL. Na rozdíl od interpretovaný regulární výrazy kompilované regulární výrazy prodloužit dobu spuštění, ale rychlejší spouštění jednotlivých metod porovnávání. Následkem toho zvýší výhoda, vyplývající ze sestavení regulárního výrazu v poměru k počtu volat metody regulárního výrazu.
Shrnutí, doporučujeme použít regulární výrazy interpretovaný při volání metody regulární výraz s konkrétní regulární výraz relativně málo. Kompilovaný regulární výrazy používejte při volání metody regulární výraz s konkrétní regulární výraz poměrně často. Je obtížné stanovit přesný práh jakou pomalejší rychlost provádění interpretovaný regulárních výrazů převažují zisky z snížené spuštění nebo práh, kdy převažují zisky z jejich rychlejší spuštění rychlostí pomalejší doby spouštění kompilované regulárních výrazů. To závisí na mnoha faktorech, včetně složitosti regulární výraz a data, která zpracovává. Určení, zda vykládat nebo zkompilované regulární výrazy nabízejí nejlepší výkon pro konkrétní aplikace scénář, můžete použít Stopwatch třídy porovnat jejich čas spuštění.
Následující příklad porovnává výkonu zkompilovaného a interpretovaný regulárních výrazů při čtení prvních deset vět a při čtení se věty textu Theodore Dreiser Financier. Výstup z příkladu ukazuje, kdy pouze deset volání metod porovnávání regulárního výrazu interpretovaný regulární výraz nabízí lepší výkon než zkompilovaný regulárního výrazu. Kompilovaný regulární výraz však nabízí lepší výkon při velký počet volání (v tomto případě přes 13 000).
Imports System.Diagnostics
Imports System.IO
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b(\w+((\r?\n)|,?\s))*\w+[.?:;!]"
Dim sw As Stopwatch
Dim match As Match
Dim ctr As Integer
Dim inFile As New StreamReader(".\Dreiser_TheFinancier.txt")
Dim input As String = inFile.ReadToEnd()
inFile.Close()
' Read first ten sentences with interpreted regex.
Console.WriteLine("10 Sentences with Interpreted Regex:")
sw = Stopwatch.StartNew()
Dim int10 As New Regex(pattern, RegexOptions.SingleLine)
match = int10.Match(input)
For ctr = 0 To 9
If match.Success Then
' Do nothing with the match except get the next match.
match = match.NextMatch()
Else
Exit For
End If
Next
sw.Stop()
Console.WriteLine(" {0} matches in {1}", ctr, sw.Elapsed)
' Read first ten sentences with compiled regex.
Console.WriteLine("10 Sentences with Compiled Regex:")
sw = Stopwatch.StartNew()
Dim comp10 As New Regex(pattern,
RegexOptions.SingleLine Or RegexOptions.Compiled)
match = comp10.Match(input)
For ctr = 0 To 9
If match.Success Then
' Do nothing with the match except get the next match.
match = match.NextMatch()
Else
Exit For
End If
Next
sw.Stop()
Console.WriteLine(" {0} matches in {1}", ctr, sw.Elapsed)
' Read all sentences with interpreted regex.
Console.WriteLine("All Sentences with Interpreted Regex:")
sw = Stopwatch.StartNew()
Dim intAll As New Regex(pattern, RegexOptions.SingleLine)
match = intAll.Match(input)
Dim matches As Integer = 0
Do While match.Success
matches += 1
' Do nothing with the match except get the next match.
match = match.NextMatch()
Loop
sw.Stop()
Console.WriteLine(" {0:N0} matches in {1}", matches, sw.Elapsed)
' Read all sentnces with compiled regex.
Console.WriteLine("All Sentences with Compiled Regex:")
sw = Stopwatch.StartNew()
Dim compAll As New Regex(pattern,
RegexOptions.SingleLine Or RegexOptions.Compiled)
match = compAll.Match(input)
matches = 0
Do While match.Success
matches += 1
' Do nothing with the match except get the next match.
match = match.NextMatch()
Loop
sw.Stop()
Console.WriteLine(" {0:N0} matches in {1}", matches, sw.Elapsed)
End Sub
End Module
' The example displays output like the following:
' 10 Sentences with Interpreted Regex:
' 10 matches in 00:00:00.0047491
' 10 Sentences with Compiled Regex:
' 10 matches in 00:00:00.0141872
' All Sentences with Interpreted Regex:
' 13,443 matches in 00:00:01.1929928
' All Sentences with Compiled Regex:
' 13,443 matches in 00:00:00.7635869
'
' >compare1
' 10 Sentences with Interpreted Regex:
' 10 matches in 00:00:00.0046914
' 10 Sentences with Compiled Regex:
' 10 matches in 00:00:00.0143727
' All Sentences with Interpreted Regex:
' 13,443 matches in 00:00:01.1514100
' All Sentences with Compiled Regex:
' 13,443 matches in 00:00:00.7432921
using System;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"\b(\w+((\r?\n)|,?\s))*\w+[.?:;!]";
Stopwatch sw;
Match match;
int ctr;
StreamReader inFile = new StreamReader(@".\Dreiser_TheFinancier.txt");
string input = inFile.ReadToEnd();
inFile.Close();
// Read first ten sentences with interpreted regex.
Console.WriteLine("10 Sentences with Interpreted Regex:");
sw = Stopwatch.StartNew();
Regex int10 = new Regex(pattern, RegexOptions.Singleline);
match = int10.Match(input);
for (ctr = 0; ctr <= 9; ctr++) {
if (match.Success)
// Do nothing with the match except get the next match.
match = match.NextMatch();
else
break;
}
sw.Stop();
Console.WriteLine(" {0} matches in {1}", ctr, sw.Elapsed);
// Read first ten sentences with compiled regex.
Console.WriteLine("10 Sentences with Compiled Regex:");
sw = Stopwatch.StartNew();
Regex comp10 = new Regex(pattern,
RegexOptions.Singleline | RegexOptions.Compiled);
match = comp10.Match(input);
for (ctr = 0; ctr <= 9; ctr++) {
if (match.Success)
// Do nothing with the match except get the next match.
match = match.NextMatch();
else
break;
}
sw.Stop();
Console.WriteLine(" {0} matches in {1}", ctr, sw.Elapsed);
// Read all sentences with interpreted regex.
Console.WriteLine("All Sentences with Interpreted Regex:");
sw = Stopwatch.StartNew();
Regex intAll = new Regex(pattern, RegexOptions.Singleline);
match = intAll.Match(input);
int matches = 0;
while (match.Success) {
matches++;
// Do nothing with the match except get the next match.
match = match.NextMatch();
}
sw.Stop();
Console.WriteLine(" {0:N0} matches in {1}", matches, sw.Elapsed);
// Read all sentnces with compiled regex.
Console.WriteLine("All Sentences with Compiled Regex:");
sw = Stopwatch.StartNew();
Regex compAll = new Regex(pattern,
RegexOptions.Singleline | RegexOptions.Compiled);
match = compAll.Match(input);
matches = 0;
while (match.Success) {
matches++;
// Do nothing with the match except get the next match.
match = match.NextMatch();
}
sw.Stop();
Console.WriteLine(" {0:N0} matches in {1}", matches, sw.Elapsed);
}
}
// The example displays the following output:
// 10 Sentences with Interpreted Regex:
// 10 matches in 00:00:00.0047491
// 10 Sentences with Compiled Regex:
// 10 matches in 00:00:00.0141872
// All Sentences with Interpreted Regex:
// 13,443 matches in 00:00:01.1929928
// All Sentences with Compiled Regex:
// 13,443 matches in 00:00:00.7635869
//
// >compare1
// 10 Sentences with Interpreted Regex:
// 10 matches in 00:00:00.0046914
// 10 Sentences with Compiled Regex:
// 10 matches in 00:00:00.0143727
// All Sentences with Interpreted Regex:
// 13,443 matches in 00:00:01.1514100
// All Sentences with Compiled Regex:
// 13,443 matches in 00:00:00.7432921
Vzorek regulární výraz použitý v příkladu, \b(\w+((\r?\n)|,?\s))*\w+[.?:;!], je definice uvedené v následující tabulce.
Maska |
Popis |
---|---|
\b |
Začne porovnání na hranici slova. |
\w+ |
Porovná jeden nebo více slovních znaků. |
(\r? \n)|,? \s) |
Odpovídat nebo vůbec carriage return následovaný znakem nového řádku nebo žádná nebo jedna čárka následovaná znakem bílého místa. |
(\w+((\r? \n)|,? \s))* |
Nula nebo více výskytů jednoho nebo více word znaky, které jsou následují žádná nebo jedna carriage return a znak nového řádku, nebo žádná nebo jedna čárka následovaná znakem bílého místa odpovídat. |
\w+ |
Porovná jeden nebo více slovních znaků. |
[.?:;!] |
Odpovídat období, otazník, dvojtečka, středník nebo vykřičníkem. |
Regulární výrazy: Kompilovaný sestavení
Na.NET Framework umožňuje také vytvořit sestavení obsahující zkompilovanou regulární výrazy. Přesunuty přístupů výkonu kompilace regulárního výrazu z běhu návrhu. Však také vyžaduje některé dodatečné práce: Je třeba předem definovat regulární výrazy a kompilace je sestavení. Kompilátor pak můžete odkazovat toto sestavení při kompilaci zdrojového kódu, který používá regulární výrazy na sestavení. Každý kompilované regulární výraz sestavení je reprezentován třídy, který je odvozen od Regex.
Regulární výrazy k sestavení kompilace, zavolejte Regex.CompileToAssembly(RegexCompilationInfo[], AssemblyName) Metoda a jejich předávání pole RegexCompilationInfo objekty představující vypracovávají, regulární výrazy a AssemblyName objekt, který obsahuje informace o sestavení vytvořen.
Doporučujeme kompilaci regulární výrazy k sestavení v následujících situacích:
Pokud jste vývojář komponenty, který chce vytvořit knihovnu opakovaně regulárních výrazů.
Pokud očekáváte nazývat neurčitý počet případů--kdekoli z jednou nebo dvakrát tisíců nebo desítky tisíc časy metod porovnávání regulárního výrazu. Na rozdíl od kompilované nebo interpretovaný regulární výrazy regulární výrazy, které jsou kompilovány do samostatných sestavení nabízejí výkon konzistentním bez ohledu na počet volání metody.
Používáte regulární výrazy kompilované optimalizace výkonu byste neměli používat odraz vytvořit sestavení, regulární výraz motoru načíst a spustit jeho metody porovnávání. To vyžaduje zabránit vytváření vzorců regulárních výrazů dynamicky, a zadejte možnosti porovnávání (například case-insensitive porovnávání) v době sestavení vytvořen. Vyžaduje také oddělit kód, který vytvoří sestavení z kódu, který používá regulární výraz.
Následující příklad ukazuje, jak vytvořit sestavení obsahující zkompilovanou regulárního výrazu. Vytvoří sestavení s názvem RegexLib.dll regulární výraz jedné třídě, SentencePattern, věta shodu regulárního výrazu, který obsahuje vzorec používaný v Interpreted vs. Kompilovaný regulární výrazy oddílu.
Imports System.Reflection
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim SentencePattern As New RegexCompilationInfo("\b(\w+((\r?\n)|,?\s))*\w+[.?:;!]",
RegexOptions.Multiline,
"SentencePattern",
"Utilities.RegularExpressions",
True)
Dim regexes() As RegexCompilationInfo = {SentencePattern}
Dim assemName As New AssemblyName("RegexLib, Version=1.0.0.1001, Culture=neutral, PublicKeyToken=null")
Regex.CompileToAssembly(regexes, assemName)
End Sub
End Module
using System;
using System.Reflection;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
RegexCompilationInfo SentencePattern =
new RegexCompilationInfo(@"\b(\w+((\r?\n)|,?\s))*\w+[.?:;!]",
RegexOptions.Multiline,
"SentencePattern",
"Utilities.RegularExpressions",
true);
RegexCompilationInfo[] regexes = { SentencePattern };
AssemblyName assemName = new AssemblyName("RegexLib, Version=1.0.0.1001, Culture=neutral, PublicKeyToken=null");
Regex.CompileToAssembly(regexes, assemName);
}
}
V příkladu je zkompilován spustitelný soubor a spustit, vytvoří sestavení s názvem RegexLib.dll. Regulární výraz je reprezentován třídu pojmenovanou Utilities.RegularExpressions.SentencePattern , je odvozen z Regex. Následující příklad používá pak kompilované regulární výraz věty extrahovat z textu Theodore Dreiser Financier.
Imports System.IO
Imports System.Text.RegularExpressions
Imports Utilities.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As New SentencePattern()
Dim inFile As New StreamReader(".\Dreiser_TheFinancier.txt")
Dim input As String = inFile.ReadToEnd()
inFile.Close()
Dim matches As MatchCollection = pattern.Matches(input)
Console.WriteLine("Found {0:N0} sentences.", matches.Count)
End Sub
End Module
' The example displays the following output:
' Found 13,443 sentences.
using System;
using System.IO;
using System.Text.RegularExpressions;
using Utilities.RegularExpressions;
public class Example
{
public static void Main()
{
SentencePattern pattern = new SentencePattern();
StreamReader inFile = new StreamReader(@".\Dreiser_TheFinancier.txt");
string input = inFile.ReadToEnd();
inFile.Close();
MatchCollection matches = pattern.Matches(input);
Console.WriteLine("Found {0:N0} sentences.", matches.Count);
}
}
// The example displays the following output:
// Found 13,443 sentences.
Převzetí Backtracking
Stroj regulární výraz obvykle používá lineární průběh přechod Vstupní řetězec a porovnat s regulárního výrazu. Však při neurčité kvantifikátory jako *, +, a ? jsou použity ve vzorci regulárního výrazu může motor regulární výraz vzdát části úspěšné částečné shody a vrátíte se do dříve uloženého stavu k hledání úspěšné shody pro celý vzorek. Tento proces je znám jako backtracking.
Poznámka |
---|
Další informace o backtracking viz Podrobnosti o chování regulárních výrazů a Mechanismus navrácení.Podrobný popis backtracking, viz Optimalizace výkonu regulární výraz, část II: Převzetí Backtracking v blogu BCL týmu. |
Podpora backtracking dává regulární výrazy výkon a flexibilitu. Umístí rovněž odpovědnost za řízení provozu motoru regulární výraz v ruce vývojáři regulárního výrazu. Protože vývojáři často nejsou vědomi této odpovědnosti, jejich zneužití backtracking nebo spoléhání na nadměrné backtracking často hraje nejvýznamnější roli při snížení výkonu regulárního výrazu. V nejhorším případě může doba provádění dvojité pro každý další znak vstupní řetězce. Ve skutečnosti pomocí nadměrně backtracking je snadné vytváření programový ekvivalent nekonečnou smyčku, pokud vstupní téměř odpovídá vzorku regulárního výrazu; regulární výraz motoru může trvat hodiny nebo i dny zpracování poměrně krátké vstupní řetězec.
Aplikace často zaplatit penalizace za použití backtracking přes skutečnost, že backtracking není podstatné shody. Například regulární výraz \b\p{Lu}\w*\b odpovídají všechna slova, které začínají velkými znak, jako následující tabulka ukazuje.
Maska |
Popis |
\b |
Začne porovnání na hranici slova. |
\p{Lu} |
Shoda velkých znaků. |
\w* |
Porovná žádný nebo více znaků slova. |
\b |
Ukončí porovnání na hranici slova. |
Protože hranici slova není stejná, nebo podmnožinu, znakem slova, není možné, že regulární výraz motoru protínají hranici slova při porovnávání znaků slova. To znamená, že pro tento regulární výraz backtracking může nikdy přispět k celkový úspěch jakékoli shoda--jej může pouze snížit výkon, protože motor regulární výraz je vynuceno uložit svůj stav pro každé úspěšné předběžné shody znakem slova.
Pokud zjistíte, že backtracking není nutné, můžete jej zakázat pomocí (?>subexpression) prvku jazyka. Následující příklad analyzuje vstupní řetězec pomocí dva regulární výrazy. První, \b\p{Lu}\w*\b, závisí na backtracking. Druhý, \b\p{Lu}(?>\w*)\b, zakáže backtracking. Výstup z příkladu ukazuje, jak vytvářejí stejný výsledek.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "This this word Sentence name Capital"
Dim pattern As String = "\b\p{Lu}\w*\b"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Value)
Next
Console.WriteLine()
pattern = "\b\p{Lu}(?>\w*)\b"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
' This
' Sentence
' Capital
'
' This
' Sentence
' Capital
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string input = "This this word Sentence name Capital";
string pattern = @"\b\p{Lu}\w*\b";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine(match.Value);
Console.WriteLine();
pattern = @"\b\p{Lu}(?>\w*)\b";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine(match.Value);
}
}
// The example displays the following output:
// This
// Sentence
// Capital
//
// This
// Sentence
// Capital
V mnoha případech je nezbytné pro odpovídající vzorce regulárního výrazu pro vstupní text backtracking. V těchto případech nadměrné backtracking můžete vážně snížit výkon a vytvořit dojem, že aplikace přestane reagovat. Zejména děje vnořené Kvantifikátory a text, který odpovídá vnější dílčím je text, který odpovídá vnitřní dílčím podmnožiny.
Například vzorec regulárního výrazu ^[0-9A-Z]([-.\w]*[0-9A-Z])*\$$ je určena odpovídající číslo dílu, který se skládá z alespoň jeden alfanumerický znak. Další znaky se může skládat z alfanumerické znaky, pomlčky, podtržítkem nebo období, když poslední znak musí být alfanumerická. Číslo dílu ukončí dolaru. V některých případech tohoto vzorku regulárního výrazu může vykazovat extrémně nízký výkon protože vnořené Kvantifikátory a dílčím [0-9A-Z] je podmnožinou dílčím [-.\w]*.
V těchto případech můžete optimalizovat výkon regulární výraz odebráním vnořené Kvantifikátory a nahrazení vnější dílčím nulové šířce dopředu nebo výrazu kontrola dozadu. Kontrola dozadu a dopředu výrazy jsou kotvy; Vstupní řetězec přesunout ukazatel ale místo toho Hledat nebo za ke kontrole, zda je zadaná podmínka splněna. Například můžete přepsat část čísla regulární výraz jako ^[0-9A-Z][-.\w]*(?<=[0-9A-Z])\$$. Tento vzorek regulární výraz je definován podle následující tabulky.
Maska |
Popis |
---|---|
^ |
Zahájí porovnávání na začátku vstupního řetězce. |
[0-9A-Z] |
Odpovídají alfanumerické znaky. Číslo dílu musí obsahovat alespoň tento znak. |
[-. \w]* |
Odpovídat nula nebo více výskytů znaku ve slově, pomlčky nebo období. |
\$ |
Shodují znak dolaru. |
(?<=[0-9A-Z]) |
Vzhled plánem zajistit alfanumerický znak předchozí koncové dolaru. |
$ |
Ukončí porovnávání na konci vstupního řetězce. |
Následující příklad ukazuje použití této regulární výraz shodovat matici obsahující čísla možné.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "^[0-9A-Z][-.\w]*(?<=[0-9A-Z])\$$"
Dim partNos() As String = { "A1C$", "A4", "A4$", "A1603D$",
"A1603D#" }
For Each input As String In partNos
Dim match As Match = Regex.Match(input, pattern)
If match.Success Then
Console.WriteLine(match.Value)
Else
Console.WriteLine("Match not found.")
End If
Next
End Sub
End Module
' The example displays the following output:
' A1C$
' Match not found.
' A4$
' A1603D$
' Match not found.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"^[0-9A-Z][-.\w]*(?<=[0-9A-Z])\$$";
string[] partNos = { "A1C$", "A4", "A4$", "A1603D$", "A1603D#" };
foreach (var input in partNos) {
Match match = Regex.Match(input, pattern);
if (match.Success)
Console.WriteLine(match.Value);
else
Console.WriteLine("Match not found.");
}
}
}
// The example displays the following output:
// A1C$
// Match not found.
// A4$
// A1603D$
// Match not found.
Regulární výraz jazyka v.NET Framework zahrnuje následující prvky jazyka lze eliminovat vnořené kvantifikátory. Další informace naleznete v tématu Seskupovací konstrukce.
Prvek jazyka |
Popis |
---|---|
(?=subexpression) |
Pozitivní kontrola dopředu nulové šířky. Vzhled předstihu zjistit aktuální pozici zda subexpression odpovídá vstupní řetězec. |
(?!subexpression) |
Negativní kontrola dopředu nulové šířky. Vzhled předstihu zjistit aktuální pozici zda subexpression neodpovídá vstupní řetězec. |
(?<=subexpression) |
Pozitivní kontrola dozadu nulové šířky. Oblast za aktuální pozici zjistit zda subexpression odpovídá vstupní řetězec. |
(?<!subexpression) |
Negativní kontrola dozadu nulové šířky. Oblast za aktuální pozici zjistit zda subexpression neodpovídá vstupní řetězec. |
Sběr pouze v případě potřeby
Regulární výrazy v.NET Framework podporuje počet seskupení konstrukce, které umožňují seskupit do jednoho nebo více podvýrazy regulárního výrazu. Nejčastěji používaný seskupení konstrukce jazyka.NET Framework regulárního výrazu jazyka jsou (dílčím), která definuje skupinu zachycení číslované a (?<název>dílčím), který definuje pojmenovanou skupinu zachycení. Konstrukce seskupení jsou zásadní pro vytváření zpětných referencí sestaví a pro definování dílčím, na který je aplikován kvantifikátor.
Použití těchto prvků jazyka má však náklady. Mohou způsobit GroupCollection objekt vrácený Match.Groups Vlastnost naplněn nejnovější nepojmenované nebo s názvem otisků a pokud zachytávání více podřetězce v řetězci vstupní jediné seskupovací konstruktor se také naplnit CaptureCollection objekt vrácený Group.Captures Vlastnost určité skupiny zachycení s více Capture objektů.
Konstrukce seskupení se často používají v regulárním výrazu pouze tak, že Kvantifikátory lze aplikovat na ně a zachytit podvýrazy těchto skupin není následně používán. Například regulární výraz \b(\w+[;,]?\s?)+[.?!] je určena pro zachycení celé věty. Následující tabulka popisuje prvky jazyka tohoto vzorku regulárního výrazu a jejich vliv na Match objektu Match.Groups a Group.Captures kolekce.
Maska |
Popis |
---|---|
\b |
Začne porovnání na hranici slova. |
\w+ |
Porovná jeden nebo více slovních znaků. |
[;,]? |
Odpovídat žádná nebo jedna čárka nebo středník. |
\s? |
Porovná žádný nebo jeden prázdný znak. |
(\w+[;,]? \s?)+ |
Jeden nebo více výskytů znaků slova následuje volitelný čárka nebo středník a volitelné znakem bílého místa odpovídat. To definuje první skupiny zachycení, která je nutná pro kombinaci více znaků slova (aplikace word) následuje symbol volitelné rozdělení se opakuje, dokud regulární výraz motoru dosáhne konec věty. |
[.?!] |
Odpovídat období, otazník a vykřičník. |
Jak ukazuje následující příklad, pokud je nalezena shoda, i GroupCollection a CapturesCollection objekty jsou zaplněny sběr dat ze shoda. V tomto případě se skupinou (\w+[;,]?\s?) existuje tak, aby + Kvantifikátor lze použít k němu, což umožňuje odpovídající vzorek regulární výraz každé slovo ve větě. V opačném případě bude odpovídat poslední slovo ve větě.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "This is one sentence. This is another."
Dim pattern As String = "\b(\w+[;,]?\s?)+[.?!]"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("Match: '{0}' at index {1}.",
match.Value, match.Index)
Dim grpCtr As Integer = 0
For Each grp As Group In match.Groups
Console.WriteLine(" Group {0}: '{1}' at index {2}.",
grpCtr, grp.Value, grp.Index)
Dim capCtr As Integer = 0
For Each cap As Capture In grp.Captures
Console.WriteLine(" Capture {0}: '{1}' at {2}.",
capCtr, cap.Value, cap.Index)
capCtr += 1
Next
grpCtr += 1
Next
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' Match: 'This is one sentence.' at index 0.
' Group 0: 'This is one sentence.' at index 0.
' Capture 0: 'This is one sentence.' at 0.
' Group 1: 'sentence' at index 12.
' Capture 0: 'This ' at 0.
' Capture 1: 'is ' at 5.
' Capture 2: 'one ' at 8.
' Capture 3: 'sentence' at 12.
'
' Match: 'This is another.' at index 22.
' Group 0: 'This is another.' at index 22.
' Capture 0: 'This is another.' at 22.
' Group 1: 'another' at index 30.
' Capture 0: 'This ' at 22.
' Capture 1: 'is ' at 27.
' Capture 2: 'another' at 30.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string input = "This is one sentence. This is another.";
string pattern = @"\b(\w+[;,]?\s?)+[.?!]";
foreach (Match match in Regex.Matches(input, pattern)) {
Console.WriteLine("Match: '{0}' at index {1}.",
match.Value, match.Index);
int grpCtr = 0;
foreach (Group grp in match.Groups) {
Console.WriteLine(" Group {0}: '{1}' at index {2}.",
grpCtr, grp.Value, grp.Index);
int capCtr = 0;
foreach (Capture cap in grp.Captures) {
Console.WriteLine(" Capture {0}: '{1}' at {2}.",
capCtr, cap.Value, cap.Index);
capCtr++;
}
grpCtr++;
}
Console.WriteLine();
}
}
}
// The example displays the following output:
// Match: 'This is one sentence.' at index 0.
// Group 0: 'This is one sentence.' at index 0.
// Capture 0: 'This is one sentence.' at 0.
// Group 1: 'sentence' at index 12.
// Capture 0: 'This ' at 0.
// Capture 1: 'is ' at 5.
// Capture 2: 'one ' at 8.
// Capture 3: 'sentence' at 12.
//
// Match: 'This is another.' at index 22.
// Group 0: 'This is another.' at index 22.
// Capture 0: 'This is another.' at 22.
// Group 1: 'another' at index 30.
// Capture 0: 'This ' at 22.
// Capture 1: 'is ' at 27.
// Capture 2: 'another' at 30.
Při použití podvýrazy pouze se na ně vztahují Kvantifikátory a nepotřebujete sebraných text, zakažte otisků skupiny. Například (?:subexpression) element jazyka zabraňuje skupiny, pro kterou platí zachytávání odpovídající podřetězce. V následujícím příkladu z předchozího příkladu vzorku regulárního výrazu je změněn na \b(?:\w+[;,]?\s?)+[.?!]. Výstup ukazuje, zabrání motoru regulární výraz vyplnění GroupCollection a CapturesCollection kolekce.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "This is one sentence. This is another."
Dim pattern As String = "\b(?:\w+[;,]?\s?)+[.?!]"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("Match: '{0}' at index {1}.",
match.Value, match.Index)
Dim grpCtr As Integer = 0
For Each grp As Group In match.Groups
Console.WriteLine(" Group {0}: '{1}' at index {2}.",
grpCtr, grp.Value, grp.Index)
Dim capCtr As Integer = 0
For Each cap As Capture In grp.Captures
Console.WriteLine(" Capture {0}: '{1}' at {2}.",
capCtr, cap.Value, cap.Index)
capCtr += 1
Next
grpCtr += 1
Next
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' Match: 'This is one sentence.' at index 0.
' Group 0: 'This is one sentence.' at index 0.
' Capture 0: 'This is one sentence.' at 0.
'
' Match: 'This is another.' at index 22.
' Group 0: 'This is another.' at index 22.
' Capture 0: 'This is another.' at 22.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string input = "This is one sentence. This is another.";
string pattern = @"\b(?:\w+[;,]?\s?)+[.?!]";
foreach (Match match in Regex.Matches(input, pattern)) {
Console.WriteLine("Match: '{0}' at index {1}.",
match.Value, match.Index);
int grpCtr = 0;
foreach (Group grp in match.Groups) {
Console.WriteLine(" Group {0}: '{1}' at index {2}.",
grpCtr, grp.Value, grp.Index);
int capCtr = 0;
foreach (Capture cap in grp.Captures) {
Console.WriteLine(" Capture {0}: '{1}' at {2}.",
capCtr, cap.Value, cap.Index);
capCtr++;
}
grpCtr++;
}
Console.WriteLine();
}
}
}
// The example displays the following output:
// Match: 'This is one sentence.' at index 0.
// Group 0: 'This is one sentence.' at index 0.
// Capture 0: 'This is one sentence.' at 0.
// Group 1: 'sentence' at index 12.
// Capture 0: 'This ' at 0.
// Capture 1: 'is ' at 5.
// Capture 2: 'one ' at 8.
// Capture 3: 'sentence' at 12.
//
// Match: 'This is another.' at index 22.
// Group 0: 'This is another.' at index 22.
// Capture 0: 'This is another.' at 22.
// Group 1: 'another' at index 30.
// Capture 0: 'This ' at 22.
// Capture 1: 'is ' at 27.
// Capture 2: 'another' at 30.
Sběr dat můžete zakázat jedním z následujících způsobů:
Použití (?:subexpression) prvku jazyka. Tento prvek zabraňuje zachycení odpovídajících podřetězců ve skupině, ke kterému se vztahuje. Podřetězec otisků ve vnořených skupinách není zakázána.
Použijte parametr ExplicitCapture. Zakáže všechny nepojmenované nebo implicitní sběr dat ve vzorku regulárního výrazu. Při použití této možnosti podřetězců pouze pojmenované skupiny definované s odpovídající (?<name>subexpression) element jazyka lze zachytit. ExplicitCapture Příznak lze předat options parametr Regex konstruktoru třídy nebo options parametr Regex statické odpovídající metody.
Použití n volbu v (?imnsx) prvku jazyka. Tato možnost zakáže všechny nepojmenované nebo implicitní sběr dat od bodu ve vzorku regulárního výrazu zobrazí prvek. Sběr dat jsou zakázány buď do konce vzorku nebo dokud (-n) možnost umožňuje nepojmenované nebo implicitní otisků. Další informace naleznete v tématu Rozdílné konstrukce.
Použití n volbu v (?imnsx:subexpression) prvku jazyka. Tato možnost zakáže všechny nepojmenované nebo implicitní otisků v subexpression. Sběr dat ve všech nepojmenované nebo implicitní vnořené skupiny zachycení jsou také zakázány.
Příbuzná témata
Title |
Popis |
---|---|
Prověřuje provádění motoru regulárního výrazu v.NET Framework. Téma se zaměřuje na flexibilitu regulární výrazy a vysvětluje vývojáře odpovědnost za zajištění účinného a robustní provoz motoru regulárního výrazu. |
|
Vysvětluje, co backtracking je a jak ovlivňuje výkon regulární výraz a zkoumá prvků jazyka, které poskytují alternativy backtracking. |
|
Popisuje prvky jazyka regulárního výrazu v.NET Framework a poskytuje odkazy na podrobnou dokumentaci pro každý prvek jazyka. |
Historie změn
Datum |
Poslední dokumenty |
Důvod |
---|---|---|
Březen 2011 |
Přidané téma. |
Rozšíření informace |