Seskupování konstrukcí v regulárních výrazech
Konstrukce pro seskupování vymezují dílčí výrazy regulárního výrazu a zachycují podřetězce vstupního řetězce. Pomocí konstrukcí seskupování můžete provést následující:
- Porovná dílčí výraz, který se opakuje ve vstupním řetězci.
- Použijte kvantifikátor na dílčí výraz, který má více elementů jazyka regulárních výrazů. Další informace o kvantifikátory naleznete v tématu Kvantifikátory.
- Do řetězce vráceného metodami Regex.ReplaceMatch.Result zahrňte dílčí výraz.
- Načtení jednotlivých dílčích výrazů z Match.Groups vlastnosti a jejich zpracování odděleně od odpovídajícího textu jako celku.
V následující tabulce jsou uvedeny konstrukty seskupení podporované modulem regulárních výrazů .NET a je uvedeno, zda jsou zachytávací nebo nezachytávací.
Seskupovací konstrukce | Zachytávání nebo nezachytávání |
---|---|
Odpovídající podvýrazy | Zachycení |
Pojmenované odpovídající dílčí výrazy | Zachycení |
Definice skupiny vyrovnávání | Zachycení |
Nezachytávající skupiny | Bez zapouzdření |
Možnosti skupiny | Nesnímající |
Pozitivní náhledové výrazy s nulovou šířkou | Bez zachytávání |
Negativní lookahead výrazy s nulovou šířkou | Bez zachycení |
Kontrolní výrazy pozitivního vzhledu s nulovou šířkou | Bez zapouzdření |
Kontrolní výrazy negativního vzhledu s nulovou šířkou | Nezachytávající |
Atomické skupiny | Bez zachycení |
Informace o skupinách a objektovém modelu regulárního výrazu naleznete v tématu Seskupování konstruktorů a objektů regulárních výrazů.
Odpovídající dílčí výrazy
Následující konstruktor seskupení zachycuje odpovídající dílčí výraz:
(
podvýraz)
Zde je subvýraz jakýkoli platný vzor regulárního výrazu. Skupiny zachycení, které používají závorky, jsou automaticky číslovány podle pořadí otevíracích závorek v regulárním výrazu zleva doprava, počínaje od 1. Pojmenované skupiny zachycení jsou však vždy seřazeny jako poslední po nenázvových skupinách zachycení. Zachycení s číslem 0 je text, který odpovídá celému vzoru regulárního výrazu.
Poznámka:
Ve výchozím nastavení (
element jazyka dílčího výrazu)
zachycuje odpovídající dílčí výraz.
RegexOptions Pokud ale parametr metody porovnávání vzorů regulárních výrazů obsahuje RegexOptions.ExplicitCapture příznak nebo pokud n
je možnost použita pro tento dílčí výraz (viz Možnosti skupiny dále v tomto článku), odpovídající dílčí výraz není zachycen.
K zachyceným skupinám můžete přistupovat čtyřmi způsoby:
Pomocí konstrukce zpětného odkazu v rámci regulárního výrazu. Odpovídající dílčí výraz se ve stejném regulárním výrazu odkazuje pomocí syntaxe
\
číslo, kde číslo je pořadové číslo zachyceného dílčího výrazu.Použitím pojmenovaného konstruktoru backreference v rámci regulárního výrazu. Odpovídající dílčí výraz se odkazuje ve stejném regulárním výrazu pomocí syntaxe
\k<
název>
, kde název je název zachycovací skupiny, nebo\k<
číslo>
, kde číslo je pořadové číslo zachycovací skupiny. Zachytávací skupina má název, který je ve výchozím nastavení shodný s jejím pořadovým číslem. Další informace naleznete v části Pojmenované odpovídající dílčí výrazy dále v tomto tématu.$
Použitím nahrazovací sekvence pro číslo v Regex.Replace nebo Match.Result při volání metody, kde číslo je pořadové číslo zachyceného dílčího výrazu.Pomocí objektu GroupCollection, který je vrácen vlastností Match.Groups, programově. Člen na pozici nula v kolekci představuje celou shodu regulárního výrazu. Každý další člen představuje odpovídající dílčí výraz. Další informace naleznete v části Seskupování konstruktorů a objektů regulárních výrazů .
Následující příklad znázorňuje regulární výraz, který identifikuje duplicitní slova v textu. Dvě zachycující skupiny vzoru regulárního výrazu představují dvě instance duplikovaného slova. Druhá instance je zachycena tak, aby hlásila počáteční pozici ve vstupním řetězci.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"(\w+)\s(\1)\W";
string input = "He said that that was the the correct answer.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
Console.WriteLine($"Duplicate '{match.Groups[1].Value}' found at positions {match.Groups[1].Index} and {match.Groups[2].Index}.");
}
}
// The example displays the following output:
// Duplicate 'that' found at positions 8 and 13.
// Duplicate 'the' found at positions 22 and 26.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "(\w+)\s(\1)\W"
Dim input As String = "He said that that was the the correct answer."
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine("Duplicate '{0}' found at positions {1} and {2}.", _
match.Groups(1).Value, match.Groups(1).Index, match.Groups(2).Index)
Next
End Sub
End Module
' The example displays the following output:
' Duplicate 'that' found at positions 8 and 13.
' Duplicate 'the' found at positions 22 and 26.
Vzor regulárního výrazu je následující:
(\w+)\s(\1)\W
Následující tabulka ukazuje, jak se interpretuje vzor regulárního výrazu.
Vzor | Popis |
---|---|
(\w+) |
Najdi jeden nebo více znaků slova. Toto je první zachytávající skupina. |
\s |
Porovná prázdný znak. |
(\1) |
Porovnejte řetězec v první zachycené skupině. Toto je druhá zachytávající skupina. Příklad ho přiřadí zachycené skupině, aby bylo možné z vlastnosti načíst Match.Index počáteční pozici duplicitního slova. |
\W |
Porovná neslovný znak včetně prázdných znaků a interpunkce. Tím zabráníte, aby vzor regulárního výrazu odpovídal slovu, které začíná slovem z první zachycené skupiny. |
Pojmenované odpovídající dílčí výrazy
Následující konstruktor seskupení zachycuje odpovídající dílčí výraz a umožňuje přístup k němu podle názvu nebo čísla:
(?<name>subexpression)
nebo:
(?'name'subexpression)
name je platný název skupiny a podvýraz je libovolný platný vzor regulárního výrazu. název nesmí obsahovat žádné interpunkční znaky a nesmí začínat číslem.
Poznámka:
Pokud parametr metody pro porovnávání vzorů regulárních výrazů zahrnuje příznak RegexOptions.ExplicitCapture, nebo pokud je na tento dílčí výraz aplikována možnost n
(viz Možnosti skupin dále v tomto tématu), jediným způsobem, jak zachytit dílčí výraz, je explicitně pojmenovat skupiny pro zachytávání.
K pojmenovaným zachyceným skupinám můžete přistupovat následujícími způsoby:
Použitím pojmenované konstrukce zpětného odkazu v rámci regulárního výrazu. Odpovídající dílčí výraz se odkazuje ve stejném regulárním výrazu pomocí syntaxe
\k<
název>
, kde název je jméno zachyceného podvýrazu.Pomocí zpětné reference v rámci konstrukce regulárního výrazu. Odpovídající dílčí výraz se odkazuje ve stejném regulárním výrazu pomocí syntaxe
\
číslo, kde číslo je pořadové číslo zachyceného dílčího výrazu. Pojmenované shodné dílčí výrazy jsou očíslovány postupně zleva doprava po shodných dílčích výrazech.Použitím sekvence nahrazení ve volání metody , kde název je název zachyceného dílčího výrazu.$
Pomocí sekvence nahrazení čísla ve Regex.Replace volání nebo Match.Result metody, kde číslo je pořadové číslo zachyceného dílčího výrazu.Programátorsky prostřednictvím objektu GroupCollection vráceného vlastností Match.Groups. Člen na pozici nula v kolekci představuje celou shodu regulárního výrazu. Každý další člen představuje odpovídající dílčí výraz. Pojmenované zachycené skupiny jsou uloženy v kolekci po očíslovaných zachycených skupinách.
Programaticky zadáním názvu subvýrazu indexeru objektu GroupCollection (v jazyce C#) nebo jeho Item[] vlastnosti (v jazyce Visual Basic).
Jednoduchý vzor regulárního výrazu znázorňuje, jak se číslované (nepojmenované) a pojmenované skupiny dají odkazovat buď prostřednictvím kódu programu, nebo pomocí syntaxe jazyka regulárních výrazů. Regulární výraz ((?<One>abc)\d+)?(?<Two>xyz)(.*)
vytvoří následující zachycené skupiny podle čísla a názvu. První zachycená skupina (číslo 0) vždy odkazuje na celý vzor. (Pojmenované skupiny jsou vždy seřazené jako poslední.)
Počet | Název | Vzor |
---|---|---|
0 | 0 (výchozí název) | ((?<One>abc)\d+)?(?<Two>xyz)(.*) |
1 | 1 (výchozí název) | ((?<One>abc)\d+) |
2 | 2 (výchozí název) | (.*) |
3 | Jeden | (?<One>abc) |
4 | Dva | (?<Two>xyz) |
Následující příklad znázorňuje regulární výraz, který identifikuje duplicitní slova a slovo, které bezprostředně následuje za každým duplicitním slovem. Vzor regulárního výrazu definuje dva pojmenované dílčí výrazy: duplicateWord
, který představuje duplikované slovo, a nextWord
který představuje slovo, které následuje za duplicitním slovem.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)";
string input = "He said that that was the the correct answer.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
Console.WriteLine($"A duplicate '{match.Groups["duplicateWord"].Value}' at position {match.Groups["duplicateWord"].Index} is followed by '{match.Groups["nextWord"].Value}'.");
}
}
// The example displays the following output:
// A duplicate 'that' at position 8 is followed by 'was'.
// A duplicate 'the' at position 22 is followed by 'correct'.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)"
Dim input As String = "He said that that was the the correct answer."
Console.WriteLine(Regex.Matches(input, pattern, RegexOptions.IgnoreCase).Count)
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine("A duplicate '{0}' at position {1} is followed by '{2}'.", _
match.Groups("duplicateWord").Value, match.Groups("duplicateWord").Index, _
match.Groups("nextWord").Value)
Next
End Sub
End Module
' The example displays the following output:
' A duplicate 'that' at position 8 is followed by 'was'.
' A duplicate 'the' at position 22 is followed by 'correct'.
Vzor regulárního výrazu je následující:
(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)
Následující tabulka ukazuje, jak se regulární výraz interpretuje.
Vzor | Popis |
---|---|
(?<duplicateWord>\w+) |
Porovná jeden nebo více znaků slova. Pojmenujte tuto zachytávací skupinu duplicateWord . |
\s |
Porovná prázdný znak. |
\k<duplicateWord> |
Porovnejte řetězec ze zachycené skupiny pojmenované duplicateWord . |
\W |
Odpovídá znakům, které nejsou součástí slova, včetně mezer a interpunkce. Tím zabráníte, aby vzor regulárního výrazu odpovídal slovu, které začíná slovem z první zachycené skupiny. |
(?<nextWord>\w+) |
Porovná jeden nebo více znaků slova. Pojmenujte tuto zachytávací skupinu nextWord . |
Název skupiny lze v regulárním výrazu opakovat. Například je možné pojmenovat digit
více než jednu skupinu, jak je znázorněno v následujícím příkladu. V případě duplicitních názvů je hodnota objektu Group určena posledním úspěšným zachycením ve vstupním řetězci. Kromě toho se naplní CaptureCollection informacemi o každém zachycení stejně, jako by to bylo v případě, že název skupiny nebyl duplikován.
V následujícím příkladu regulární výraz \D+(?<digit>\d+)\D+(?<digit>\d+)?
obsahuje dva výskyty skupiny s názvem digit
. První digit
pojmenovaná skupina zachycuje jeden nebo více číslicových znaků. Druhá digit
pojmenovaná skupina zachytí žádný nebo jeden výskyt jedné nebo více ciferných znaků. Jak ukazuje výstup z příkladu, pokud druhá zachycená skupina úspěšně odpovídá textu, hodnota tohoto textu definuje hodnotu objektu Group . Pokud druhá zachytácí skupina neodpovídá vstupnímu řetězci, definuje hodnota poslední úspěšné shody hodnotu objektu Group .
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
String pattern = @"\D+(?<digit>\d+)\D+(?<digit>\d+)?";
String[] inputs = { "abc123def456", "abc123def" };
foreach (var input in inputs) {
Match m = Regex.Match(input, pattern);
if (m.Success) {
Console.WriteLine($"Match: {m.Value}");
for (int grpCtr = 1; grpCtr < m.Groups.Count; grpCtr++) {
Group grp = m.Groups[grpCtr];
Console.WriteLine($"Group {grpCtr}: {grp.Value}");
for (int capCtr = 0; capCtr < grp.Captures.Count; capCtr++)
Console.WriteLine($" Capture {capCtr}: {grp.Captures[capCtr].Value}");
}
}
else {
Console.WriteLine("The match failed.");
}
Console.WriteLine();
}
}
}
// The example displays the following output:
// Match: abc123def456
// Group 1: 456
// Capture 0: 123
// Capture 1: 456
//
// Match: abc123def
// Group 1: 123
// Capture 0: 123
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\D+(?<digit>\d+)\D+(?<digit>\d+)?"
Dim inputs() As String = {"abc123def456", "abc123def"}
For Each input As String In inputs
Dim m As Match = Regex.Match(input, pattern)
If m.Success Then
Console.WriteLine("Match: {0}", m.Value)
For grpCtr As Integer = 1 to m.Groups.Count - 1
Dim grp As Group = m.Groups(grpCtr)
Console.WriteLine("Group {0}: {1}", grpCtr, grp.Value)
For capCtr As Integer = 0 To grp.Captures.Count - 1
Console.WriteLine(" Capture {0}: {1}", capCtr,
grp.Captures(capCtr).Value)
Next
Next
Else
Console.WriteLine("The match failed.")
End If
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' Match: abc123def456
' Group 1: 456
' Capture 0: 123
' Capture 1: 456
'
' Match: abc123def
' Group 1: 123
' Capture 0: 123
Následující tabulka ukazuje, jak se regulární výraz interpretuje.
Vzor | Popis |
---|---|
\D+ |
Porovná jednu nebo více nedecimálních číslic. |
(?<digit>\d+) |
Porovná jednu nebo více desetinných číslic. Přiřaďte shodu pojmenované digit skupině. |
\D+ |
Najděte jeden nebo více znaků, které nejsou desetinnými číslicemi. |
(?<digit>\d+)? |
Porovná žádný nebo jeden výskyt jednoho nebo více desetinných číslic. Přiřaďte shodu pojmenované skupině digit . |
Definice vyvažovací skupiny
Definice skupiny vyrovnávání odstraní definici dříve definované skupiny a uloží v aktuální skupině interval mezi dříve definovanou skupinou a aktuální skupinou. Tento konstruktor seskupení má následující formát:
(?<name1-name2>subexpression)
nebo:
(?'name1-name2' subexpression)
Tady je name1 aktuální skupina (volitelné), name2 je dříve definovaná skupina a dílčí výraz je libovolný platný vzor regulárního výrazu. Definice skupiny vyrovnávání odstraní definici názvu2 a uloží interval mezi názvem 2 a názvem1 v názvu1. Pokud není definována žádná skupina name2, vyhodnocení se vrací zpět. Vzhledem k tomu, že odstranění poslední definice name2 odhalí předchozí definici name2, umožňuje tato konstrukce použít zásobník zachycení pro skupinu name2 jako čítač pro sledování vnořených konstrukcí, jako jsou závorky nebo otevírací a zavírací závorky.
Definice vyrovnávací skupiny používá název2 jako zásobník. Počáteční znak každého vnořeného konstruktoru je umístěn ve skupině a v její Group.Captures kolekci. Když je zavírací znak nalezen, odpovídající počáteční znak je odstraněn ze skupiny a kolekce Captures se zmenší o jeden. Po spárování počátečních a uzavíracích znaků všech vnořených konstrukcí je název2 prázdný.
Poznámka:
Po úpravě regulárního výrazu v následujícím příkladu tak, aby používal odpovídající levý a pravý znak vnořené konstrukce, můžete ho použít ke zpracování většiny vnořených konstruktorů, jako jsou matematické výrazy nebo řádky kódu programu, které obsahují více volání vnořených metod.
Následující příklad používá definici skupiny vyrovnávání, která odpovídá levým a pravému úhlu závorek (<>) ve vstupním řetězci. Příklad definuje dvě pojmenované skupiny Open
a Close
, které se používají jako zásobník pro sledování párů úhlových závorek. Každá zachycená levá hranatá závorka se vloží do kolekce zachycení skupiny Open
, a každá zachycená pravá hranatá závorka se vloží do kolekce zachycení skupiny Close
. Definice skupiny vyrovnávání zajišťuje, že je pro každou levou špičatou závorku odpovídající pravá špičatá závorka. Pokud tomu tak není, konečný podpattern, (?(Open)(?!))
, je vyhodnocen pouze v případě, že skupina Open
není prázdná (a že tedy všechny vnořené konstrukce nebyly uzavřeny). Pokud se vyhodnocuje konečný podpattern, shoda selže, protože (?!)
podpattern je záporný kontrolní výraz s nulovou šířkou, který vždy selže.
using System;
using System.Text.RegularExpressions;
class Example
{
public static void Main()
{
string pattern = "^[^<>]*" +
"(" +
"((?'Open'<)[^<>]*)+" +
"((?'Close-Open'>)[^<>]*)+" +
")*" +
"(?(Open)(?!))$";
string input = "<abc><mno<xyz>>";
Match m = Regex.Match(input, pattern);
if (m.Success == true)
{
Console.WriteLine($"Input: \"{input}\" \nMatch: \"{m}\"");
int grpCtr = 0;
foreach (Group grp in m.Groups)
{
Console.WriteLine($" Group {grpCtr}: {grp.Value}");
grpCtr++;
int capCtr = 0;
foreach (Capture cap in grp.Captures)
{
Console.WriteLine($" Capture {capCtr}: {cap.Value}");
capCtr++;
}
}
}
else
{
Console.WriteLine("Match failed.");
}
}
}
// The example displays the following output:
// Input: "<abc><mno<xyz>>"
// Match: "<abc><mno<xyz>>"
// Group 0: <abc><mno<xyz>>
// Capture 0: <abc><mno<xyz>>
// Group 1: <mno<xyz>>
// Capture 0: <abc>
// Capture 1: <mno<xyz>>
// Group 2: <xyz
// Capture 0: <abc
// Capture 1: <mno
// Capture 2: <xyz
// Group 3: >
// Capture 0: >
// Capture 1: >
// Capture 2: >
// Group 4:
// Group 5: mno<xyz>
// Capture 0: abc
// Capture 1: xyz
// Capture 2: mno<xyz>
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "^[^<>]*" & _
"(" + "((?'Open'<)[^<>]*)+" & _
"((?'Close-Open'>)[^<>]*)+" + ")*" & _
"(?(Open)(?!))$"
Dim input As String = "<abc><mno<xyz>>"
Dim rgx AS New Regex(pattern) '
Dim m As Match = Regex.Match(input, pattern)
If m.Success Then
Console.WriteLine("Input: ""{0}"" " & vbCrLf & "Match: ""{1}""", _
input, m)
Dim grpCtr As Integer = 0
For Each grp As Group In m.Groups
Console.WriteLine(" Group {0}: {1}", grpCtr, grp.Value)
grpCtr += 1
Dim capCtr As Integer = 0
For Each cap As Capture In grp.Captures
Console.WriteLine(" Capture {0}: {1}", capCtr, cap.Value)
capCtr += 1
Next
Next
Else
Console.WriteLine("Match failed.")
End If
End Sub
End Module
' The example displays the following output:
' Input: "<abc><mno<xyz>>"
' Match: "<abc><mno<xyz>>"
' Group 0: <abc><mno<xyz>>
' Capture 0: <abc><mno<xyz>>
' Group 1: <mno<xyz>>
' Capture 0: <abc>
' Capture 1: <mno<xyz>>
' Group 2: <xyz
' Capture 0: <abc
' Capture 1: <mno
' Capture 2: <xyz
' Group 3: >
' Capture 0: >
' Capture 1: >
' Capture 2: >
' Group 4:
' Group 5: mno<xyz>
' Capture 0: abc
' Capture 1: xyz
' Capture 2: mno<xyz>
Vzor regulárního výrazu je:
^[^<>]*(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*(?(Open)(?!))$
Regulární výraz se interpretuje takto:
Vzor | Popis |
---|---|
^ |
Začněte na začátku řetězce. |
[^<>]* |
Porovná nula nebo více znaků, které nejsou levé nebo pravé hranaté závorky. |
(?'Open'<) |
Identifikuje levou úhlovou závorku a přiřadí ji do skupiny pojmenované Open . |
[^<>]* |
Porovná nula nebo více znaků, které nejsou levé nebo pravé hranaté závorky. |
((?'Open'<)[^<>]*)+ |
Porovná jeden nebo více výskytů levé úhlové závorky, po které následuje nula nebo více znaků, které nejsou levé nebo pravé úhlové závorky. Toto je druhá zachytávající skupina. |
(?'Close-Open'>) |
Spárujte pravou úhlovou závorku, přiřaďte podřetězec mezi Open skupinou a aktuální skupinou ke skupině Close , a odstraňte definici skupiny Open . |
[^<>]* |
Porovná žádný nebo více výskytů libovolného znaku, který není levý ani pravý úhel závorka. |
((?'Close-Open'>)[^<>]*)+ |
Porovná jeden nebo více výskytů pravé špičaté závorky, za kterými následuje nula nebo více výskytů libovolného znaku, který není levá ani pravá špičatá závorka. Při porovnávání pravé úhlové závorky přiřaďte podřetězec mezi skupinou Open a aktuální skupinou ke skupině Close a odstraňte definici skupiny Open . Toto je třetí zachytávající skupina. |
(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)* |
Porovná nula nebo více výskytů následujícího vzoru: jeden nebo více výskytů levé úhlové závorky následované nulou nebo více znaky, které nejsou úhlovými závorkami, za kterými následuje jeden nebo více výskytů pravé úhlové závorky, za kterými následuje nula nebo více výskytů znaků, které nejsou úhlovými závorkami. Při porovnávání pravé úhlové závorky odstraňte definici Open skupiny a přiřaďte podřetězec mezi Open skupinou a aktuální skupinou ke Close skupině. Toto je první zachytávající skupina. |
(?(Open)(?!)) |
Pokud skupina Open existuje, zrušte shodu, pokud je možné spárovat prázdný řetězec, ale neposuňte pozici modulu regulárních výrazů v řetězci. Jedná se o negativní asert s nulovou šířkou. Protože prázdný řetězec je vždy implicitně přítomný ve vstupním řetězci, tato shoda vždy selže. Selhání této shody značí, že úhlové závorky nejsou správně vyvážené. |
$ |
Ověřit konec vstupního řetězce. |
Poslední dílčí výraz (?(Open)(?!))
, označuje, zda jsou vnořené konstrukce ve vstupním řetězci správně vyváženy (například zda je každá levá úhlová závorka spárována pravou úhlovou závorkou). Používá podmíněné porovnávání na základě platné zachycené skupiny. Další informace naleznete v tématu Alternační konstrukce. Pokud je skupina Open
definována, modul regulárních výrazů se snaží použít dílčí výraz (?!)
ve vstupním řetězci. Skupina Open
by měla být definována pouze v případě, že jsou vnořené konstrukce nevyvážené. Proto by vzor, který se má shodovat ve vstupním řetězci, měl být vzor, který vždy způsobí selhání shody. V tomto případě je negativní vyhledávací kontrolní výraz nulové šířky, (?!)
který vždy selže, protože prázdný řetězec je vždy implicitně přítomný na další pozici ve vstupním řetězci.
V příkladu modul regulárních výrazů vyhodnotí vstupní řetězec "<abc><mno<xyz>>", jak je znázorněno v následující tabulce.
Krok | Vzor | Výsledek |
---|---|---|
1 | ^ |
Zahájí shodu na začátku vstupního řetězce. |
2 | [^<>]* |
Hledá znaky, které nejsou špičaté závorky, před levou špičatou závorkou. Nenajde žádné shody. |
3 | (((?'Open'<) |
Odpovídá levé hranaté závorce v "<abc>" a přiřadí ji skupině Open . |
4 | [^<>]* |
Shoduje se s "abc". |
5 | )+ |
"abc<" je hodnota druhé zachycené skupiny. Další znak ve vstupním řetězci není levá špičatá závorka, takže regulární výraz se nevrátí zpět do podvzorce (?'Open'<)[^<>]*) . |
6 | ((?'Close-Open'>) |
Odpovídá pravé lomené závorce v "<abc>", přiřadí "abc", což je podřetězec mezi skupinou Open a pravou lomenou závorkou, ke skupině Close , a odstraní aktuální hodnotu ("<") skupiny Open , čímž ji ponechá prázdnou. |
7 | [^<>]* |
Hledá znaky, které nejsou znakem úhlové závorky, za pravou úhlovou závorkou; nenalezne žádné shody. |
8 | )+ |
Hodnota třetí zachycené skupiny je ">". Další znak ve vstupním řetězci není pravá úhlová závorka, takže překladač regulárních výrazů se nevrátí zpět do podvzorce ((?'Close-Open'>)[^<>]*) . |
9 | )* |
Hodnota první zachycené skupiny je "abc<>". Dalším znakem ve vstupním řetězci je levá úhlová závorka, takže mechanismus regulárních výrazů se vrátí zpět do podvzoru (((?'Open'<) . |
10 | (((?'Open'<) |
Odpovídá levé ostré závorce v < mno a přiřazuje ji ke skupině Open . Její Group.Captures kolekce teď má jednu hodnotu "<". |
11 | [^<>]* |
Odpovídá "mno". |
12 | )+ |
"<mno" je hodnota druhé zachycené skupiny. Dalším znakem ve vstupním řetězci je levá úhlová závorka, takže modul regulárních výrazů se vrátí k podvzoru (?'Open'<)[^<>]*) . |
13 | (((?'Open'<) |
Odpovídá levé lomené závorce v< xyz> a přiřadí ji ke skupině Open . Kolekce Group.Captures skupiny Open teď obsahuje dva záznamy: levá špičatá závorka z "<mno" a levá špičatá závorka z "<xyz>". |
14 | [^<>]* |
Odpovídá výrazu "xyz". |
15 | )+ |
"<xyz" je hodnota druhé zachycené skupiny. Další znak ve vstupním řetězci není levá špičatá závorka, takže modul regulárních výrazů se nevrátí zpět do podvzoru (?'Open'<)[^<>]*) . |
16 | ((?'Close-Open'>) |
Odpovídá pravé úhlové závorce ve "<xyz>". "xyz", přiřadí podřetězce mezi Open skupinou a pravou úhlovou závorku ke Close skupině a odstraní aktuální hodnotu Open skupiny. Hodnota předchozího zachycení (levá ostrá závorka v "<mno") se stane aktuální hodnotou skupiny Open . Kolekce skupiny Open nyní obsahuje jedno zachycení, levou špičatou závorku z "<xyz>". |
17 | [^<>]* |
Hledá znaky jiné než úhlové závorky, nenalezne žádné shody. |
18 | )+ |
Hodnota třetí zachycené skupiny je ">". Dalším znakem ve vstupním řetězci je pravá úhlová závorka, takže modul regulárních výrazů se vrátí zpět do podvzorce ((?'Close-Open'>)[^<>]*) . |
19 | ((?'Close-Open'>) |
Odpovídá konečné pravé hranaté závorce v "xyz>>", přiřadí "mno<xyz>" (podřetězec mezi skupinou Open a pravou hranatou závorkou) skupině Close a odstraní aktuální hodnotu skupiny Open . Skupina Open je teď prázdná. |
20 | [^<>]* |
Hledá znaky kromě špičatých závorek. Nenajde žádnou shodu. |
21 | )+ |
Hodnota třetí zachycené skupiny je ">". Další znak ve vstupním řetězci není pravá úhlová závorka, takže výrazový modul se nevrátí zpět do subvzoru ((?'Close-Open'>)[^<>]*) . |
22 | )* |
Hodnota první zachycené skupiny je "<mno<xyz>>". Další znak ve vstupním řetězci není levá ostrá závorka, takže vyhledávač regulárních výrazů se nevrátí zpět do podpatternu (((?'Open'<) . |
23 | (?(Open)(?!)) |
Skupina Open není definována, takže se nepokusí žádná shoda. |
24 | $ |
Odpovídá konci vstupního řetězce. |
Skupiny bez zachytávání
Následující konstrukce seskupení nezachytí podřetězec, který odpovídá dílčímu výrazu:
(?:subexpression)
Podvýraz je jakýkoli platný vzor regulárního výrazu. Nezachytávací skupina se obvykle používá, když je na skupinu aplikován kvantifikátor, ale dílčí řetězce zachycené touto skupinou nejsou důležité.
Poznámka:
Pokud regulární výraz obsahuje vnořené seskupovací konstrukce, vnější neukládající seskupovací konstrukce se nevztahuje na vnitřní vnořené skupinové konstrukce.
Následující příklad ukazuje regulární výraz, který obsahuje nepojmenované skupiny. Všimněte si, že výstup neobsahuje žádné zachycené skupiny.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"(?:\b(?:\w+)\W*)+\.";
string input = "This is a short sentence.";
Match match = Regex.Match(input, pattern);
Console.WriteLine($"Match: {match.Value}");
for (int ctr = 1; ctr < match.Groups.Count; ctr++)
Console.WriteLine($" Group {ctr}: {match.Groups[ctr].Value}");
}
}
// The example displays the following output:
// Match: This is a short sentence.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "(?:\b(?:\w+)\W*)+\."
Dim input As String = "This is a short sentence."
Dim match As Match = Regex.Match(input, pattern)
Console.WriteLine("Match: {0}", match.Value)
For ctr As Integer = 1 To match.Groups.Count - 1
Console.WriteLine(" Group {0}: {1}", ctr, match.Groups(ctr).Value)
Next
End Sub
End Module
' The example displays the following output:
' Match: This is a short sentence.
Regulární výraz (?:\b(?:\w+)\W*)+\.
odpovídá větě, která je ukončena tečkou. Vzhledem k tomu, že regulární výraz se zaměřuje na věty a ne na jednotlivá slova, používají se konstrukty seskupení výhradně jako kvantifikátory. Vzor regulárního výrazu je interpretován, jak je znázorněno v následující tabulce.
Vzor | Popis |
---|---|
\b |
Zahajte shodu na hranici slova. |
(?:\w+) |
Porovná jeden nebo více znaků slova. Nepřiřaďte odpovídající text zachycené skupině. |
\W* |
Shoduje nula nebo více neslovných znaků. |
(?:\b(?:\w+)\W*)+ |
Porovná vzor jednoho nebo více znaků slova začínajících na hranici slova, za nímž následuje nula nebo více neslovných znaků, jednou nebo vícekrát. Nepřiřaďte odpovídající text zachycené skupině. |
\. |
Najděte odpovídající období. |
Možnosti skupiny
Následující konstruktor seskupení použije nebo zakáže zadané možnosti v rámci dílčího výrazu:
(?imnsx-imnsx:
podvýraz)
Podvýraz je libovolný platný vzor regulárního výrazu. Například (?i-s:)
zapne nerozlišování velkých a malých písmen a povolí režim s jedním řádkem. Další informace o vložených možnostech, které můžete zadat, naleznete v tématu Možnosti regulárního výrazu.
Poznámka:
Pomocí konstruktoru System.Text.RegularExpressions.Regex třídy nebo statické metody můžete určit možnosti, které se vztahují na celý regulární výraz, nikoli na dílčí výraz. Pomocí jazykové konstrukce (?imnsx-imnsx)
můžete také určit vložené možnosti, které se použijí po určitém bodu regulárního výrazu.
Konstrukce možností skupiny není záchytnou skupinou. To znamená, že ačkoli jakákoli část řetězce zachyceného dílčím výrazem je zahrnuta do shody, není zahrnuta do zachycené skupiny ani použita k naplnění objektuGroupCollection.
Například regulární výraz \b(?ix: d \w+)\s
v následujícím příkladu používá vložené možnosti v konstruktoru seskupení k povolení porovnávání bez rozlišování velkých a malých písmen a ignorování prázdného místa při identifikaci všech slov, která začínají písmenem "d". Regulární výraz je definován, jak je znázorněno v následující tabulce.
Vzor | Popis |
---|---|
\b |
Začněte shodu na hranici slova. |
(?ix: d \w+) |
Použitím porovnávání bez ohledu na velikost písmen a ignorováním mezer v tomto vzoru vyhledejte "d", který je následován jedním nebo více znaky slova. |
\s |
Porovná prázdný znak. |
string pattern = @"\b(?ix: d \w+)\s";
string input = "Dogs are decidedly good pets.";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine($"'{match.Value}// found at index {match.Index}.");
// The example displays the following output:
// 'Dogs // found at index 0.
// 'decidedly // found at index 9.
Dim pattern As String = "\b(?ix: d \w+)\s"
Dim input As String = "Dogs are decidedly good pets."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("'{0}' found at index {1}.", match.Value, match.Index)
Next
' The example displays the following output:
' 'Dogs ' found at index 0.
' 'decidedly ' found at index 9.
Aserce pozitivního vyhledávání s nulovou šířkou
Následující konstrukce seskupení definuje prediktivní výraz s nulovou šířkou:
(?=
podvýraz)
Tady je dílčí výraz libovolný vzor regulárního výrazu. Aby byla shoda úspěšná, musí vstupní řetězec odpovídat vzoru regulárního výrazu v dílčím výrazu, i když odpovídající podřetězc není zahrnut do výsledku shody. Kontrolní výraz pozitivního vyhledávání s nulovou šířkou se nevrátí zpět.
Na konci vzoru regulárního výrazu se obvykle nachází kladné kontrolní výrazy s nulovou šířkou. Definuje podřetězec, který musí být nalezen na konci řetězce, aby došlo ke shodě, ale neměl by být zahrnut do shody. Je také užitečné pro zabránění nadměrnému vracení zpět. Pomocí pozitivního tvrzení s nulovou šířkou můžete zajistit, aby konkrétní zachycená skupina začala textem, který odpovídá podmnožině vzoru definovaného pro danou zachycenou skupinu. Pokud například zachycovací skupina odpovídá po sobě jdoucím znakům slova, můžete použít pozitivní prognózu s nulovou šířkou, která vyžaduje, aby první znak byl velkým abecedním písmenem.
Následující příklad používá aserci s nulovou šířkou a pozitivním podmíněním, aby odpovídala slovu, které předchází slovesu "is" ve vstupním řetězci.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"\b\w+(?=\sis\b)";
string[] inputs = { "The dog is a Malamute.",
"The island has beautiful birds.",
"The pitch missed home plate.",
"Sunday is a weekend day." };
foreach (string input in inputs)
{
Match match = Regex.Match(input, pattern);
if (match.Success)
Console.WriteLine($"'{match.Value}' precedes 'is'.");
else
Console.WriteLine($"'{input}' does not match the pattern.");
}
}
}
// The example displays the following output:
// 'dog' precedes 'is'.
// 'The island has beautiful birds.' does not match the pattern.
// 'The pitch missed home plate.' does not match the pattern.
// 'Sunday' precedes 'is'.
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b\w+(?=\sis\b)"
Dim inputs() As String = {"The dog is a Malamute.", _
"The island has beautiful birds.", _
"The pitch missed home plate.", _
"Sunday is a weekend day."}
For Each input As String In inputs
Dim match As Match = Regex.Match(input, pattern)
If match.Success Then
Console.WriteLine("'{0}' precedes 'is'.", match.Value)
Else
Console.WriteLine("'{0}' does not match the pattern.", input)
End If
Next
End Sub
End Module
' The example displays the following output:
' 'dog' precedes 'is'.
' 'The island has beautiful birds.' does not match the pattern.
' 'The pitch missed home plate.' does not match the pattern.
' 'Sunday' precedes 'is'.
Regulární výraz \b\w+(?=\sis\b)
se interpretuje, jak je znázorněno v následující tabulce.
Vzor | Popis |
---|---|
\b |
Začněte na hranici slova. |
\w+ |
Porovná jeden nebo více znaků slova. |
(?=\sis\b) |
Určete, jestli jsou znaky slova následované prázdným znakem a řetězcem "is", který končí na hranici slova. Pokud ano, shoda byla úspěšná. |
Výrazy negativních nulových šířkových podmínek anticipačního vyhledávání
Následující konstrukce seskupení definuje asert negativního pohledu s nulovou šířkou:
(?!
podvýraz)
Zde je podvýraz libovolný vzor regulárního výrazu. Aby byla shoda úspěšná, vstupní řetězec nesmí odpovídat vzoru regulárního výrazu v dílčím výrazu, i když odpovídající řetězec není součástí výsledku shody.
Kontrolní výraz negativního vyhledávání s nulovou šířkou se obvykle používá buď na začátku, nebo na konci regulárního výrazu. Na začátku regulárního výrazu může definovat konkrétní vzor, který by se neměl shodovat, když začátek regulárního výrazu definuje podobný, ale obecnější vzor, který se má shodovat. V tomto případě se často používá k omezení navracení. Na konci regulárního výrazu může být definován dílčí výraz, který nemůže být součástí konečné shody.
Následující příklad definuje regulární výraz, který používá nulové šířky předvýraz na začátku regulárního výrazu, aby odpovídal slovům, která nezačínají na "un".
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"\b(?!un)\w+\b";
string input = "unite one unethical ethics use untie ultimate";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
Console.WriteLine(match.Value);
}
}
// The example displays the following output:
// one
// ethics
// use
// ultimate
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b(?!un)\w+\b"
Dim input As String = "unite one unethical ethics use untie ultimate"
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
' one
' ethics
' use
' ultimate
Regulární výraz \b(?!un)\w+\b
se interpretuje, jak je znázorněno v následující tabulce.
Vzor | Popis |
---|---|
\b |
Začněte vyhledávání na hranici slova. |
(?!un) |
Určete, jestli jsou následující dva znaky "un". Pokud tomu tak není, shoda je možná. |
\w+ |
Porovná jeden nebo více znaků slova. |
\b |
Ukončete shodu na hranici slova. |
Následující příklad definuje regulární výraz, který používá hledaný výraz nulové šířky na konci regulárního výrazu, aby odpovídal slovům, která nekončí interpunkčním znakem.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"\b\w+\b(?!\p{P})";
string input = "Disconnected, disjointed thoughts in a sentence fragment.";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine(match.Value);
}
}
// The example displays the following output:
// disjointed
// thoughts
// in
// a
// sentence
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b\w+\b(?!\p{P})"
Dim input As String = "Disconnected, disjointed thoughts in a sentence fragment."
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:
' disjointed
' thoughts
' in
' a
' sentence
Regulární výraz \b\w+\b(?!\p{P})
se interpretuje, jak je znázorněno v následující tabulce.
Vzor | Popis |
---|---|
\b |
Zahajte porovnání na hranici slova. |
\w+ |
Porovná jeden nebo více znaků slova. |
\b |
Ukončete shodu na hranici slova. |
\p{P}) |
Pokud další znak není interpunkční znak (například tečka nebo čárka), shoda je úspěšná. |
Výrazy pozitivního zpětného pohledu s nulovou šířkou
Následující konstrukce definuje pozitivní lookbehind s nulovou délkou:
(?<=
podvýraz)
Tady je dílčí výraz libovolný vzor regulárního výrazu. Aby byla shoda úspěšná, podvýraz se musí vyskytovat na vstupním řetězci vlevo od aktuální pozice, ačkoliv subexpression
není zahrnut ve výsledku shody. Kontrolní výraz pozitivního vzhledu s nulovou šířkou se nevrátí zpět.
Aserce hledící vzad s nulovou šířkou se obvykle používají na začátku regulárních výrazů. Vzor, který definují, slouží jako předpoklad pro shodu, i když není součástí výsledku shody.
Následující příklad odpovídá posledním dvěma číslicím roku pro jednadvacáté století (to znamená, že číslice "20" předchází odpovídajícímu řetězci).
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string input = "2010 1999 1861 2140 2009";
string pattern = @"(?<=\b20)\d{2}\b";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine(match.Value);
}
}
// The example displays the following output:
// 10
// 09
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "2010 1999 1861 2140 2009"
Dim pattern As String = "(?<=\b20)\d{2}\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:
' 10
' 09
Vzor (?<=\b20)\d{2}\b
regulárního výrazu je interpretován, jak je znázorněno v následující tabulce.
Vzor | Popis |
---|---|
\d{2} |
Porovná dvě desítkové číslice. |
(?<=\b20) |
Pokračujte v zápasu, pokud jsou dvě číslice před číslicemi "20" na hranici slova. |
\b |
Ukončete zápas na hranici slova. |
Atributy pozitivního zpětného pohledu s nulovou šířkou se také používají k omezení zpětného sledování, pokud poslední znaky v zachycené skupině musí být podmnožinou znaků, které odpovídají patternu regulárního výrazu dané skupiny. Pokud například skupina zachycuje všechny po sobě jdoucí znaky slova, můžete použít kladné zpětné ověření s nulovou šířkou k tomu, abyste vyžadovali, že poslední znak je písmeno.
Negativní pozadí s nulovou šířkou v regulárních výrazech
Následující seskupovací konstrukce definuje výraz pro negativní zpětné vyhledávání s nulovou šířkou.
(?<!
podvýraz)
Zde je dílčí výraz libovolným vzorem regulárního výrazu. Aby byla shoda úspěšná, podvýraz nesmí nastat ve vstupním řetězci vlevo od aktuální pozice. Jakýkoli podřetězec, který se neshoduje subexpression
, ale není součástí výsledku shody.
Výrazy s nulovou šířkou pro záporné zpětné sledování se obvykle používají na začátku regulárních výrazů. Vzor, který definují, vylučuje shodu v následujícím řetězci. Používají se také k omezení zpětného sledování, pokud poslední znak nebo znaky v zachycené skupině nesmí být jedním nebo více znaky, které odpovídají vzoru regulárního výrazu této skupiny. Například pokud skupina zachycuje všechny po sobě jdoucí znaky slova, můžete použít pozitivní lookbehind výraz s nulovou délkou, který požaduje, aby poslední znak nebyl podtržítko (_).
Následující příklad odpovídá datu pro libovolný den v týdnu, který není víkend (to znamená, že není sobota ani neděle).
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string[] dates = { "Monday February 1, 2010",
"Wednesday February 3, 2010",
"Saturday February 6, 2010",
"Sunday February 7, 2010",
"Monday, February 8, 2010" };
string pattern = @"(?<!(Saturday|Sunday) )\b\w+ \d{1,2}, \d{4}\b";
foreach (string dateValue in dates)
{
Match match = Regex.Match(dateValue, pattern);
if (match.Success)
Console.WriteLine(match.Value);
}
}
}
// The example displays the following output:
// February 1, 2010
// February 3, 2010
// February 8, 2010
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim dates() As String = {"Monday February 1, 2010", _
"Wednesday February 3, 2010", _
"Saturday February 6, 2010", _
"Sunday February 7, 2010", _
"Monday, February 8, 2010"}
Dim pattern As String = "(?<!(Saturday|Sunday) )\b\w+ \d{1,2}, \d{4}\b"
For Each dateValue As String In dates
Dim match As Match = Regex.Match(dateValue, pattern)
If match.Success Then
Console.WriteLine(match.Value)
End If
Next
End Sub
End Module
' The example displays the following output:
' February 1, 2010
' February 3, 2010
' February 8, 2010
Vzor (?<!(Saturday|Sunday) )\b\w+ \d{1,2}, \d{4}\b
regulárního výrazu je interpretován, jak je znázorněno v následující tabulce.
Vzor | Popis |
---|---|
\b |
Začněte shodu na hranici slova. |
\w+ |
Porovná jeden nebo více znaků slova následovaných prázdným znakem. |
\d{1,2}, |
Porovná jednu nebo dvě desetinné číslice následované prázdným znakem a čárkou. |
\d{4}\b |
Porovnejte čtyři desetinné číslice a ukončete srovnání na hranici slova. |
(?<!(Saturday|Sunday) ) |
Pokud před shodou následuje něco jiného než řetězce "Sobota" nebo "Neděle" následované mezerou, je shoda úspěšná. |
Atomické skupiny
Následující konstrukce seskupení představuje atomickou skupinu (známou v některých dalších modulech regulárních výrazů jako nevytvářející zpětnou vazbu dílčí výraz, atomický dílčí výraz nebo jednorázový dílčí výraz):
(?>
podvýraz)
Tady je dílčí výraz libovolnou podobou regulárního výrazu.
Obvykle, pokud regulární výraz zahrnuje nepovinný nebo alternativní vzor a shoda není nalezena, modul regulárních výrazů se může rozvětvit do několika směrů, aby odpovídal vstupnímu řetězci se vzorem. Pokud se shoda nenajde, když vezme první větev, modul regulárních výrazů se může vrátit zpět do bodu, kde se pokusil o první shodu, a pokusit se o shodu pomocí druhé větve. Tento proces může pokračovat, dokud se nezkouší všechny větve.
Konstruktor (?>
jazyka dílčího výrazu)
zakáže navracení. Modul regulárních výrazů bude odpovídat tolika znakům ve vstupním řetězci, kolik může. Pokud není možná žádná další shoda, nevrátí se k pokusu o alternativní shody vzorů. (To znamená, že dílčí výraz se shoduje pouze s těmi řetězci, které by odpovídaly dílčímu výrazu samotnému; nepokouší se shodovat řetězec na základě dílčího výrazu a následujících dílčích výrazů.)
Tato možnost se doporučuje, pokud víte, že navracení nebude úspěšné. Zabránění tomu, aby modul regulárních výrazů prováděl zbytečné vyhledávání, zlepšuje výkon.
Následující příklad ukazuje, jak atomová skupina mění výsledky shody vzoru. Regulární výraz se zpětným zpracováním úspěšně odpovídá řadě opakovaných znaků následovaných dalším výskytem stejného znaku na hranici slova, ale regulární výraz bez zpětného zpracování nikoli.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string[] inputs = { "cccd.", "aaad", "aaaa" };
string back = @"(\w)\1+.\b";
string noback = @"(?>(\w)\1+).\b";
foreach (string input in inputs)
{
Match match1 = Regex.Match(input, back);
Match match2 = Regex.Match(input, noback);
Console.WriteLine($"{input}: ");
Console.Write(" Backtracking : ");
if (match1.Success)
Console.WriteLine(match1.Value);
else
Console.WriteLine("No match");
Console.Write(" Nonbacktracking: ");
if (match2.Success)
Console.WriteLine(match2.Value);
else
Console.WriteLine("No match");
}
}
}
// The example displays the following output:
// cccd.:
// Backtracking : cccd
// Nonbacktracking: cccd
// aaad:
// Backtracking : aaad
// Nonbacktracking: aaad
// aaaa:
// Backtracking : aaaa
// Nonbacktracking: No match
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim inputs() As String = {"cccd.", "aaad", "aaaa"}
Dim back As String = "(\w)\1+.\b"
Dim noback As String = "(?>(\w)\1+).\b"
For Each input As String In inputs
Dim match1 As Match = Regex.Match(input, back)
Dim match2 As Match = Regex.Match(input, noback)
Console.WriteLine("{0}: ", input)
Console.Write(" Backtracking : ")
If match1.Success Then
Console.WriteLine(match1.Value)
Else
Console.WriteLine("No match")
End If
Console.Write(" Nonbacktracking: ")
If match2.Success Then
Console.WriteLine(match2.Value)
Else
Console.WriteLine("No match")
End If
Next
End Sub
End Module
' The example displays the following output:
' cccd.:
' Backtracking : cccd
' Nonbacktracking: cccd
' aaad:
' Backtracking : aaad
' Nonbacktracking: aaad
' aaaa:
' Backtracking : aaaa
' Nonbacktracking: No match
Regulární výraz (?>(\w)\1+).\b
bez zpětného navracení je definován, jak je znázorněno v následující tabulce.
Vzor | Popis |
---|---|
(\w) |
Porovná jediný znak odpovídající slovu a přiřadí ho první zachytávací skupině. |
\1+ |
Porovná hodnotu prvního zachyceného podřetězce jednou nebo vícekrát. |
. |
Odpovídá libovolnému znaku. |
\b |
Ukončete shodu na hranici slova. |
(?>(\w)\1+) |
Najděte jeden nebo více výskytů duplicitního znaku ve slově, ale nevracejte se zpět, abyste porovnali poslední znak na hranici slova. |
Seskupování konstruktorů a objektů regulárních výrazů
Podřetězce, které odpovídají skupině zachycující regulárního výrazu, jsou reprezentovány objekty System.Text.RegularExpressions.Group, které lze načíst z objektu System.Text.RegularExpressions.GroupCollection, jenž je vrácen vlastností Match.Groups. Objekt GroupCollection se vyplní následujícím způsobem:
- První Group objekt v kolekci (objekt na indexu nula) představuje celou shodu.
- Další sada Group objektů představuje nepojmenované (číslované) zachycovací skupiny. Zobrazí se v pořadí, ve kterém jsou definovány v regulárním výrazu zleva doprava. Hodnoty indexu těchto skupin jsou v rozsahu od 1 do počtu nepojmenovaných zachycených skupin v kolekci. (Index konkrétní skupiny je ekvivalentní číslovanému zpětnému odkazu. Další informace o zpětných odkazech naleznete v tématu Konstrukce zpětných odkazů.)
- Poslední sada Group objektů představuje pojmenované skupiny zachytávání. Zobrazí se v pořadí, ve kterém jsou definovány v regulárním výrazu zleva doprava. Hodnota indexu první pojmenované zachytávací skupiny je o jednu větší než index poslední nepojmenované zachytávací skupiny. Pokud v regulárním výrazu nejsou žádné nepojmenované skupiny, hodnota indexu první pojmenované zachytávací skupiny je jedna.
Pokud použijete kvantifikátor na zachytávací skupinu, odpovídající objekt Group, Capture.Value, Capture.Index a Capture.Length vlastnosti odrážejí poslední podřetězec, který byl zachycen zachytávací skupinou. Můžete načíst úplnou sadu podřetězců, které jsou zachyceny skupinami s kvantifikátory, z objektu CaptureCollection, který je vrácen vlastností Group.Captures.
Následující příklad vysvětluje vztah mezi Group objekty a Capture objekty.
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"(\b(\w+)\W+)+";
string input = "This is a short sentence.";
Match match = Regex.Match(input, pattern);
Console.WriteLine($"Match: '{match.Value}'");
for (int ctr = 1; ctr < match.Groups.Count; ctr++)
{
Console.WriteLine($" Group {ctr}: '{match.Groups[ctr].Value}'");
int capCtr = 0;
foreach (Capture capture in match.Groups[ctr].Captures)
{
Console.WriteLine($" Capture {capCtr}: '{capture.Value}'");
capCtr++;
}
}
}
}
// The example displays the following output:
// Match: 'This is a short sentence.'
// Group 1: 'sentence.'
// Capture 0: 'This '
// Capture 1: 'is '
// Capture 2: 'a '
// Capture 3: 'short '
// Capture 4: 'sentence.'
// Group 2: 'sentence'
// Capture 0: 'This'
// Capture 1: 'is'
// Capture 2: 'a'
// Capture 3: 'short'
// Capture 4: 'sentence'
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "(\b(\w+)\W+)+"
Dim input As String = "This is a short sentence."
Dim match As Match = Regex.Match(input, pattern)
Console.WriteLine("Match: '{0}'", match.Value)
For ctr As Integer = 1 To match.Groups.Count - 1
Console.WriteLine(" Group {0}: '{1}'", ctr, match.Groups(ctr).Value)
Dim capCtr As Integer = 0
For Each capture As Capture In match.Groups(ctr).Captures
Console.WriteLine(" Capture {0}: '{1}'", capCtr, capture.Value)
capCtr += 1
Next
Next
End Sub
End Module
' The example displays the following output:
' Match: 'This is a short sentence.'
' Group 1: 'sentence.'
' Capture 0: 'This '
' Capture 1: 'is '
' Capture 2: 'a '
' Capture 3: 'short '
' Capture 4: 'sentence.'
' Group 2: 'sentence'
' Capture 0: 'This'
' Capture 1: 'is'
' Capture 2: 'a'
' Capture 3: 'short'
' Capture 4: 'sentence'
Vzor regulárního výrazu (\b(\w+)\W+)+
extrahuje jednotlivá slova z řetězce. Je definován tak, jak je uvedeno v následující tabulce.
Vzor | Popis |
---|---|
\b |
Začněte na hranici slova. |
(\w+) |
Porovná jeden nebo více znaků slova. Tyto znaky společně tvoří slovo. Toto je druhá zachytávající skupina. |
\W+ |
Porovná jeden nebo více neslovných znaků. |
(\b(\w+)\W+) |
Porovná vzor jednoho nebo více znaků slova, za kterými následuje jeden nebo více neslovných znaků jednou nebo vícekrát. Toto je první zachytávající skupina. |
Druhá zachycovací skupina odpovídá každému slovu věty. První zachycená skupina odpovídá každému slovu spolu s interpunkcí a prázdným místem, které následují za tímto slovem. Objekt Group , jehož index je 2, poskytuje informace o textu, který odpovídá druhé skupině zachycení. Úplná sada slov zachycených zachycující skupinou je k dispozici z objektu CaptureCollection vráceného vlastností Group.Captures.