A reguláris kifejezés viselkedésének részletei
A .NET reguláris kifejezésmotor egy visszakövetéses reguláris kifejezésegyeztető, amely egy hagyományos, nemdeterminista véges automaton (NFA) motort tartalmaz, például a Perl, a Python, az Emacs és a Tcl által használt motort. Ez megkülönbözteti a gyorsabb, de korlátozottabb, tiszta reguláris kifejezés determinisztikus véges automaton (DFA) motorok, mint például az awk, egrep vagy lex. Ez megkülönbözteti a szabványosított, de lassabb POSIX NFA-któl is. Az alábbi szakasz a reguláris kifejezésmotorok három típusát ismerteti, és ismerteti, hogy a .NET-ben a reguláris kifejezések miért implementálhatók hagyományos NFA-motor használatával.
Az NFA motor előnyei
Amikor a DFA-motorok mintaegyeztetéseket végeznek, a feldolgozási sorrendjüket a bemeneti sztring vezérli. A motor a bemeneti sztring elején kezdődik, és egymás után halad annak megállapításához, hogy a következő karakter megegyezik-e a reguláris kifejezésmintával. Garantálhatják, hogy a lehető leghosszabb sztringgel egyeznek. Mivel soha nem tesztelik kétszer ugyanazt a karaktert, a DFA-motorok nem támogatják a visszakövetést. Mivel azonban a DFA-motor csak véges állapotot tartalmaz, nem egyezik a háttérbeli mintával, és mivel nem hoz létre explicit bővítést, nem tudja rögzíteni a részexpressziókat.
A DFA-motorokkal ellentétben, amikor a hagyományos NFA-motorok mintaegyezést végeznek, a feldolgozási sorrendjüket a reguláris kifejezésminta vezérli. Mivel egy adott nyelvi elemet dolgoz fel, a motor kapzsi egyezést használ; vagyis a bemeneti sztringek közül a lehető legtöbbnek felel meg. De az állapotot is menti, miután sikeresen megfelelteti a részexpressziót. Ha egy egyezés végül meghiúsul, a motor visszatérhet egy mentett állapotba, hogy további egyezéseket próbáljon ki. A sikeres szubexpressziós egyezés megszüntetésének folyamata, hogy a normál kifejezés későbbi nyelvi elemei is egyezhessenek, visszakövetésnek nevezzük. Az NFA-motorok visszakövetéssel tesztelik a reguláris kifejezések minden lehetséges kiterjesztését egy adott sorrendben, és elfogadják az első egyezést. Mivel a hagyományos NFA-motor egy sikeres egyezéshez a reguláris kifejezés egy adott kiterjesztését állítja össze, képes rögzíteni a szubexpressziós egyezéseket és az egyező háttérrendszereket. Mivel azonban egy hagyományos NFA-visszakövetés, többször is meglátogathatja ugyanazt az állapotot, ha különböző útvonalakon érkezik az állapothoz. Ennek eredményeként exponenciálisan lassan futhat a legrosszabb esetben. Mivel a hagyományos NFA-motor elfogadja az első találatot, más (esetleg hosszabb) egyezéseket is felderítetlenül hagyhat.
A POSIX NFA-motorok olyanok, mint a hagyományos NFA-motorok, azzal a kivétellel, hogy mindaddig visszalépnek, amíg nem garantálják, hogy a lehető leghosszabb egyezést találták. Ennek eredményeképpen a POSIX NFA-motor lassabb, mint a hagyományos NFA-motor, és POSIX NFA-motor használatakor a visszakövetéses keresés sorrendjének módosításával nem lehet rövidebb egyezést előnyben részesni egy hosszabbnál.
A hagyományos NFA-motorokat a programozók előnyben részesítik, mivel nagyobb vezérlést biztosítanak a sztringegyezés felett, mint a DFA vagy a POSIX NFA motor. Bár a legrosszabb esetben lassan futnak, a kétértelműségeket csökkentő és a visszakövetést korlátozó mintázatok használatával irányíthatja őket a lineáris vagy polinomiális idő szerinti egyezések keresésére. Más szóval, bár az NFA-motorok a teljesítmény és a rugalmasság érdekében kereskednek a teljesítménnyel, a legtöbb esetben jó elfogadható teljesítményt nyújtanak, ha egy reguláris kifejezés jól meg van írva, és elkerüli azokat az eseteket, amikor a visszakövetés exponenciálisan csökkenti a teljesítményt.
Feljegyzés
A túlzott visszalépés által okozott teljesítménybírságról és a rendszeres kifejezések megkerülésére szolgáló módszerekről a Visszakövetés című témakörben olvashat.
.NET-motor képességei
A hagyományos NFA-motor előnyeinek kihasználásához a .NET reguláris kifejezésmotor olyan szerkezeteket tartalmaz, amelyek lehetővé teszik a programozók számára a visszakövetési motor irányítását. Ezekkel a szerkezetekkel gyorsabban kereshet egyezéseket, vagy előnyben részesítheti az egyes bővítéseket másokkal szemben.
A .NET reguláris kifejezésmotor további funkciói a következők:
Lusta kvantátorok:
??
,*?
,+?
n{
,
m.}?
Ezek a szerkezetek azt jelzik a visszakövetési motornak, hogy először a minimális számú ismétlést keresse meg. Ezzel szemben a szokásos kapzsi kvantátorok először az ismétlések maximális számának próbálnak megfelelni. Az alábbi példa a kettő közötti különbséget szemlélteti. A reguláris kifejezések egy számmal végződő mondatot egyeznek meg, és a rögzítési csoport célja a szám kinyerése. A reguláris kifejezés.+(\d+)\.
tartalmazza a kapzsi kvantitálót.+
, amely miatt a reguláris kifejezésmotor csak a szám utolsó számjegyét rögzíti. Ezzel szemben a reguláris kifejezés.+?(\d+)\.
tartalmazza a lusta kvantitálót.+?
, amely miatt a reguláris kifejezésmotor a teljes számot rögzíti.using System; using System.Text.RegularExpressions; public class Example { public static void Main() { string greedyPattern = @".+(\d+)\."; string lazyPattern = @".+?(\d+)\."; string input = "This sentence ends with the number 107325."; Match match; // Match using greedy quantifier .+. match = Regex.Match(input, greedyPattern); if (match.Success) Console.WriteLine("Number at end of sentence (greedy): {0}", match.Groups[1].Value); else Console.WriteLine("{0} finds no match.", greedyPattern); // Match using lazy quantifier .+?. match = Regex.Match(input, lazyPattern); if (match.Success) Console.WriteLine("Number at end of sentence (lazy): {0}", match.Groups[1].Value); else Console.WriteLine("{0} finds no match.", lazyPattern); } } // The example displays the following output: // Number at end of sentence (greedy): 5 // Number at end of sentence (lazy): 107325
Imports System.Text.RegularExpressions Module Example Public Sub Main() Dim greedyPattern As String = ".+(\d+)\." Dim lazyPattern As String = ".+?(\d+)\." Dim input As String = "This sentence ends with the number 107325." Dim match As Match ' Match using greedy quantifier .+. match = Regex.Match(input, greedyPattern) If match.Success Then Console.WriteLine("Number at end of sentence (greedy): {0}", match.Groups(1).Value) Else Console.WriteLine("{0} finds no match.", greedyPattern) End If ' Match using lazy quantifier .+?. match = Regex.Match(input, lazyPattern) If match.Success Then Console.WriteLine("Number at end of sentence (lazy): {0}", match.Groups(1).Value) Else Console.WriteLine("{0} finds no match.", lazyPattern) End If End Sub End Module ' The example displays the following output: ' Number at end of sentence (greedy): 5 ' Number at end of sentence (lazy): 107325
A reguláris kifejezés kapzsi és lusta verziói az alábbi táblázatban látható módon vannak definiálva:
Minta Leírás .+
(kapzsi kvantáló)Egyezzen meg egy karakter legalább egy előfordulásával. Ez azt eredményezi, hogy a reguláris kifejezésmotor megfelel a teljes sztringnek, majd szükség szerint visszalép a minta többi részével való egyeztetéshez. .+?
(lusta kvantáló)Egyezzen meg egy karakter legalább egy előfordulásával, de a lehető legkevesebbet egyezzen meg. (\d+)
Egyezzen meg legalább egy numerikus karaktert, és rendelje hozzá az első rögzítési csoporthoz. \.
Pont egyeztetése. A lusta kvantátorokról további információt a Quantifiersben talál.
Pozitív lookahead:
(?=
subexpression)
. Ez a funkció lehetővé teszi, hogy a visszakövetési motor visszatérjen a szöveg ugyanazon pontjának, miután megfelelteti a részkinyomást. Az azonos pozícióból kiinduló minták ellenőrzésével hasznos lehet a teljes szövegben való keresés. Azt is lehetővé teszi a motor számára, hogy ellenőrizze, hogy létezik-e részszúrás a találat végén anélkül, hogy beleszámítottuk volna az alászúrást a megfeleltetett szövegbe. Az alábbi példa a pozitív lookahead használatával nyeri ki a szavakat egy mondatban, amelyet nem követnek írásjelek.using System; using System.Text.RegularExpressions; public class Example { public static void Main() { string pattern = @"\b[A-Z]+\b(?=\P{P})"; string input = "If so, what comes next?"; foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase)) Console.WriteLine(match.Value); } } // The example displays the following output: // If // what // comes
Imports System.Text.RegularExpressions Module Example Public Sub Main() Dim pattern As String = "\b[A-Z]+\b(?=\P{P})" Dim input As String = "If so, what comes next?" 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: ' If ' what ' comes
A reguláris kifejezés
\b[A-Z]+\b(?=\P{P})
az alábbi táblázatban látható módon van definiálva.Minta Leírás \b
Kezdje el az egyezést egy szóhatáron. [A-Z]+
Egy vagy több betűrendben szereplő karakternek felel meg. Mivel a Regex.Matches metódust a RegexOptions.IgnoreCase beállítással hívjuk meg, az összehasonlítás kis- és nagybetűket nem érzékelyítő. \b
Egy szóhatáron fejezd be az egyezést. (?=\P{P})
Nézze meg előre, hogy a következő karakter írásjel-e. Ha nem, a találat sikeres lesz. A pozitív lookahead-állításokkal kapcsolatos további információkért lásd a csoportosítási szerkezeteket.
Negatív lookahead:
(?!
subexpression)
. Ez a funkció csak akkor teszi lehetővé egy kifejezés egyeztetését, ha egy alkifejezés nem egyezik. Ez hatékony a keresések metszéséhez, mivel gyakran egyszerűbb kifejezéseket adni egy olyan esethez, amelyet ki kell küszöbölni, mint egy kifejezést olyan esetekben, amelyeket fel kell venni. Nehéz például kifejezést írni olyan szavakhoz, amelyek nem "nem" betűvel kezdődnek. Az alábbi példa negatív keresőfejet használ a kizárásukhoz.using System; using System.Text.RegularExpressions; public class Example { public static void Main() { string pattern = @"\b(?!non)\w+\b"; string input = "Nonsense is not always non-functional."; foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase)) Console.WriteLine(match.Value); } } // The example displays the following output: // is // not // always // functional
Imports System.Text.RegularExpressions Module Example Public Sub Main() Dim pattern As String = "\b(?!non)\w+\b" Dim input As String = "Nonsense is not always non-functional." 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: ' is ' not ' always ' functional
A reguláris kifejezésminta
\b(?!non)\w+\b
az alábbi táblázatban látható módon van definiálva.Minta Leírás \b
Kezdje el az egyezést egy szóhatáron. (?!non)
Előretekintve győződjön meg arról, hogy az aktuális sztring nem "nem" betűvel kezdődik. Ha igen, a találat meghiúsul. (\w+)
Egy vagy több szó karakterének egyeztetése. \b
Egy szóhatáron fejezd be az egyezést. A negatív lookahead-állításokkal kapcsolatos további információkért lásd a csoportosítási szerkezeteket.
Feltételes kiértékelés:
(?(
kifejezés)
igen|
nem)
és(?(
név)
igen|
nem)
, ahol a kifejezés egy egyeztetendő alkifejezés, a név egy rögzítési csoport neve, igen az a sztring, amelyet egyezni kell, ha a kifejezés egyezik, vagy a név érvényes, nem üres rögzített csoport, és nem az a részexpresszió, amelyet egyezni kell, ha a kifejezés nem egyezik, vagy a név nem érvényes, nem üres rögzített csoport. Ez a funkció lehetővé teszi a motor számára, hogy több alternatív mintát használjon egy korábbi alexpressziós egyezés eredményétől vagy a nulla szélességű állítás eredményétől függően. Ez lehetővé teszi a háttérhatás hatékonyabb formáját, amely lehetővé teszi például a szubexpresszió egyeztetését attól függően, hogy egy korábbi alexpresszió megfelelt-e. Az alábbi példában szereplő reguláris kifejezés megegyezik a nyilvános és belső használatra szánt bekezdésekkel. A csak belső használatra szánt bekezdések címkével<PRIVATE>
kezdődnek. A reguláris kifejezésminta^(?<Pvt>\<PRIVATE\>\s)?(?(Pvt)((\w+\p{P}?\s)+)|((\w+\p{P}?\s)+))\r?$
feltételes kiértékeléssel rendeli hozzá a nyilvános és belső használatra szánt bekezdések tartalmát a rögzítési csoportok elkülönítéséhez. Ezek a bekezdések ezután másképp kezelhetők.using System; using System.Text.RegularExpressions; public class Example { public static void Main() { string input = "<PRIVATE> This is not for public consumption." + Environment.NewLine + "But this is for public consumption." + Environment.NewLine + "<PRIVATE> Again, this is confidential.\n"; string pattern = @"^(?<Pvt>\<PRIVATE\>\s)?(?(Pvt)((\w+\p{P}?\s)+)|((\w+\p{P}?\s)+))\r?$"; string publicDocument = null, privateDocument = null; foreach (Match match in Regex.Matches(input, pattern, RegexOptions.Multiline)) { if (match.Groups[1].Success) { privateDocument += match.Groups[1].Value + "\n"; } else { publicDocument += match.Groups[3].Value + "\n"; privateDocument += match.Groups[3].Value + "\n"; } } Console.WriteLine("Private Document:"); Console.WriteLine(privateDocument); Console.WriteLine("Public Document:"); Console.WriteLine(publicDocument); } } // The example displays the following output: // Private Document: // This is not for public consumption. // But this is for public consumption. // Again, this is confidential. // // Public Document: // But this is for public consumption.
Imports System.Text.RegularExpressions Module Example Public Sub Main() Dim input As String = "<PRIVATE> This is not for public consumption." + vbCrLf + _ "But this is for public consumption." + vbCrLf + _ "<PRIVATE> Again, this is confidential." + vbCrLf Dim pattern As String = "^(?<Pvt>\<PRIVATE\>\s)?(?(Pvt)((\w+\p{P}?\s)+)|((\w+\p{P}?\s)+))\r?$" Dim publicDocument As String = Nothing Dim privateDocument As String = Nothing For Each match As Match In Regex.Matches(input, pattern, RegexOptions.Multiline) If match.Groups(1).Success Then privateDocument += match.Groups(1).Value + vbCrLf Else publicDocument += match.Groups(3).Value + vbCrLf privateDocument += match.Groups(3).Value + vbCrLf End If Next Console.WriteLine("Private Document:") Console.WriteLine(privateDocument) Console.WriteLine("Public Document:") Console.WriteLine(publicDocument) End Sub End Module ' The example displays the following output: ' Private Document: ' This is not for public consumption. ' But this is for public consumption. ' Again, this is confidential. ' ' Public Document: ' But this is for public consumption.
A reguláris kifejezésminta az alábbi táblázatban látható módon van definiálva.
Minta Leírás ^
Kezdje el az egyezést a sor elején. (?<Pvt>\<PRIVATE\>\s)?
Egyezik a sztring <PRIVATE>
nullával vagy egy előfordulásával, majd egy szóköz karakterrel. Rendelje hozzá az egyezést egy rögzítési csoporthozPvt
.(?(Pvt)((\w+\p{P}?\s)+)
Ha a rögzítési Pvt
csoport létezik, egy vagy több szókarakter egy vagy több előfordulását, majd egy nulla vagy egy írásjelelválasztót, majd egy szóköz karaktert kell használnia. Rendelje hozzá az alsztringet az első rögzítési csoporthoz.|((\w+\p{P}?\s)+))
Ha a Pvt
rögzítési csoport nem létezik, egy vagy több szókarakter egy vagy több előfordulásával egyezik, amelyet nulla vagy egy írásjelelválasztó követ, majd egy szóköz karakterrel. Rendelje hozzá az alsztringet a harmadik rögzítési csoporthoz.\r?$
Egy vonal vagy a sztring végének egyeztetése. A feltételes értékeléssel kapcsolatos további információkért lásd : Alternation Constructs.
Csoportdefiníciók kiegyensúlyozása:
(?<
name1-
name2>
subexpression.)
Ez a funkció lehetővé teszi, hogy a reguláris kifejezésmotor nyomon kövesse a beágyazott szerkezeteket, például zárójeleket vagy nyitó és záró zárójeleket. Példa: Csoportosítási szerkezetek.Atomcsoportok:
(?>
szubexpresszió)
. Ez a funkció lehetővé teszi, hogy a visszakövetési motor garantálja, hogy egy alexpresszió csak az adott alexpresszióhoz talált első egyezésnek felel meg, mintha a kifejezés az azt tartalmazó kifejezésétől függetlenül fut. Ha nem használja ezt a szerkezetet, a nagyobb kifejezésből származó keresések visszakövetése megváltoztathatja az alkifejezések viselkedését. A reguláris kifejezés(a+)\w
például egy vagy több "a" karaktert, valamint egy "a" karaktersorozatot követő szókaraktereknek felel meg, és az "a" karakterek sorozatát rendeli hozzá az első rögzítési csoporthoz. Ha azonban a bemeneti sztring végső karaktere szintén "a", akkor a nyelvi elem megfelelteti\w
, és nem szerepel a rögzített csoportban.using System; using System.Text.RegularExpressions; public class Example { public static void Main() { string[] inputs = { "aaaaa", "aaaaab" }; string backtrackingPattern = @"(a+)\w"; Match match; foreach (string input in inputs) { Console.WriteLine("Input: {0}", input); match = Regex.Match(input, backtrackingPattern); Console.WriteLine(" Pattern: {0}", backtrackingPattern); if (match.Success) { Console.WriteLine(" Match: {0}", match.Value); Console.WriteLine(" Group 1: {0}", match.Groups[1].Value); } else { Console.WriteLine(" Match failed."); } } Console.WriteLine(); } } // The example displays the following output: // Input: aaaaa // Pattern: (a+)\w // Match: aaaaa // Group 1: aaaa // Input: aaaaab // Pattern: (a+)\w // Match: aaaaab // Group 1: aaaaa
Imports System.Text.RegularExpressions Module Example Public Sub Main() Dim inputs() As String = {"aaaaa", "aaaaab"} Dim backtrackingPattern As String = "(a+)\w" Dim match As Match For Each input As String In inputs Console.WriteLine("Input: {0}", input) match = Regex.Match(input, backtrackingPattern) Console.WriteLine(" Pattern: {0}", backtrackingPattern) If match.Success Then Console.WriteLine(" Match: {0}", match.Value) Console.WriteLine(" Group 1: {0}", match.Groups(1).Value) Else Console.WriteLine(" Match failed.") End If Next Console.WriteLine() End Sub End Module ' The example displays the following output: ' Input: aaaaa ' Pattern: (a+)\w ' Match: aaaaa ' Group 1: aaaa ' Input: aaaaab ' Pattern: (a+)\w ' Match: aaaaab ' Group 1: aaaaa
A normál kifejezés
((?>a+))\w
megakadályozza ezt a viselkedést. Mivel az összes egymást követő "a" karakter visszakövetés nélkül egyezik, az első rögzítési csoport az összes egymást követő "a" karaktert tartalmazza. Ha az "a" karaktereket nem követi legalább egy karakter az "a" karakteren kívül, az egyezés meghiúsul.using System; using System.Text.RegularExpressions; public class Example { public static void Main() { string[] inputs = { "aaaaa", "aaaaab" }; string nonbacktrackingPattern = @"((?>a+))\w"; Match match; foreach (string input in inputs) { Console.WriteLine("Input: {0}", input); match = Regex.Match(input, nonbacktrackingPattern); Console.WriteLine(" Pattern: {0}", nonbacktrackingPattern); if (match.Success) { Console.WriteLine(" Match: {0}", match.Value); Console.WriteLine(" Group 1: {0}", match.Groups[1].Value); } else { Console.WriteLine(" Match failed."); } } Console.WriteLine(); } } // The example displays the following output: // Input: aaaaa // Pattern: ((?>a+))\w // Match failed. // Input: aaaaab // Pattern: ((?>a+))\w // Match: aaaaab // Group 1: aaaaa
Imports System.Text.RegularExpressions Module Example Public Sub Main() Dim inputs() As String = {"aaaaa", "aaaaab"} Dim nonbacktrackingPattern As String = "((?>a+))\w" Dim match As Match For Each input As String In inputs Console.WriteLine("Input: {0}", input) match = Regex.Match(input, nonbacktrackingPattern) Console.WriteLine(" Pattern: {0}", nonbacktrackingPattern) If match.Success Then Console.WriteLine(" Match: {0}", match.Value) Console.WriteLine(" Group 1: {0}", match.Groups(1).Value) Else Console.WriteLine(" Match failed.") End If Next Console.WriteLine() End Sub End Module ' The example displays the following output: ' Input: aaaaa ' Pattern: ((?>a+))\w ' Match failed. ' Input: aaaaab ' Pattern: ((?>a+))\w ' Match: aaaaab ' Group 1: aaaaa
Az atomi csoportokkal kapcsolatos további információkért lásd a Csoportosítási szerkezetek című témakört.
Jobbról balra történő egyeztetés, amely az osztálykonstruktor vagy a RegexOptions.RightToLeft statikus példányegyeztetési módszer beállításának Regex megadásával van megadva. Ez a funkció akkor hasznos, ha jobbról balra keres, nem pedig balról jobbra, vagy olyan esetekben, amikor hatékonyabb egyezést kezdeni a minta jobb oldalán a bal helyett. Az alábbi példa szemlélteti, hogy a jobbról balra történő egyeztetés megváltoztathatja a kapzsi kvantátorok viselkedését. A példa két olyan mondatot keres, amely egy számmal végződik. A kapzsi kvantitátort
+
használó balról jobbra keresés a mondat hat számjegyének egyikével egyezik, míg a jobbról balra történő keresés mind a hat számjegyre egyezik. A reguláris kifejezési minta leírását a szakasz korábbi, lusta kvantitátorait szemléltető példában találja.using System; using System.Text.RegularExpressions; public class Example { public static void Main() { string greedyPattern = @".+(\d+)\."; string input = "This sentence ends with the number 107325."; Match match; // Match from left-to-right using lazy quantifier .+?. match = Regex.Match(input, greedyPattern); if (match.Success) Console.WriteLine("Number at end of sentence (left-to-right): {0}", match.Groups[1].Value); else Console.WriteLine("{0} finds no match.", greedyPattern); // Match from right-to-left using greedy quantifier .+. match = Regex.Match(input, greedyPattern, RegexOptions.RightToLeft); if (match.Success) Console.WriteLine("Number at end of sentence (right-to-left): {0}", match.Groups[1].Value); else Console.WriteLine("{0} finds no match.", greedyPattern); } } // The example displays the following output: // Number at end of sentence (left-to-right): 5 // Number at end of sentence (right-to-left): 107325
Imports System.Text.RegularExpressions Module Example Public Sub Main() Dim greedyPattern As String = ".+(\d+)\." Dim input As String = "This sentence ends with the number 107325." Dim match As Match ' Match from left-to-right using lazy quantifier .+?. match = Regex.Match(input, greedyPattern) If match.Success Then Console.WriteLine("Number at end of sentence (left-to-right): {0}", match.Groups(1).Value) Else Console.WriteLine("{0} finds no match.", greedyPattern) End If ' Match from right-to-left using greedy quantifier .+. match = Regex.Match(input, greedyPattern, RegexOptions.RightToLeft) If match.Success Then Console.WriteLine("Number at end of sentence (right-to-left): {0}", match.Groups(1).Value) Else Console.WriteLine("{0} finds no match.", greedyPattern) End If End Sub End Module ' The example displays the following output: ' Number at end of sentence (left-to-right): 5 ' Number at end of sentence (right-to-left): 107325
A jobbról balra történő egyeztetésről további információt a Reguláris kifejezés beállításai című témakörben talál.
Pozitív és negatív lookbehind:
(?<=
subexpression)
for positive lookbehind, and(?<!
subexpression)
for negative lookbehind. Ez a funkció hasonló a lookahead funkcióhoz, amelyet a jelen témakör korábbi részében tárgyalunk. Mivel a reguláris kifejezésmotor teljes jobbról balra egyeztetést tesz lehetővé, a reguláris kifejezések korlátlan megjelenést tesz lehetővé. A pozitív és negatív lookbehind a kvantátorok beágyazásának elkerülésére is használható, ha a beágyazott alexpresszió egy külső kifejezés szuperhalmaza. Az ilyen beágyazott kvantitátorokkal rendelkező reguláris kifejezések gyakran gyenge teljesítményt nyújtanak. Az alábbi példa például azt ellenőrzi, hogy egy sztring alfanumerikus karakterrel kezdődik és végződik, és hogy a sztring bármely más karaktere egy nagyobb részhalmaz egyike. Az e-mail-címek ellenőrzésére használt reguláris kifejezés egy részét képezi; További információ: Útmutató: Ellenőrizze, hogy a sztringek érvényes e-mail formátumban vannak-e.using System; using System.Text.RegularExpressions; public class Example { public static void Main() { string[] inputs = { "jack.sprat", "dog#", "dog#1", "me.myself", "me.myself!" }; string pattern = @"^[A-Z0-9]([-!#$%&'.*+/=?^`{}|~\w])*(?<=[A-Z0-9])$"; foreach (string input in inputs) { if (Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase)) Console.WriteLine("{0}: Valid", input); else Console.WriteLine("{0}: Invalid", input); } } } // The example displays the following output: // jack.sprat: Valid // dog#: Invalid // dog#1: Valid // me.myself: Valid // me.myself!: Invalid
Imports System.Text.RegularExpressions Module Example Public Sub Main() Dim inputs() As String = {"jack.sprat", "dog#", "dog#1", "me.myself", "me.myself!"} Dim pattern As String = "^[A-Z0-9]([-!#$%&'.*+/=?^`{}|~\w])*(?<=[A-Z0-9])$" For Each input As String In inputs If Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase) Then Console.WriteLine("{0}: Valid", input) Else Console.WriteLine("{0}: Invalid", input) End If Next End Sub End Module ' The example displays the following output: ' jack.sprat: Valid ' dog#: Invalid ' dog#1: Valid ' me.myself: Valid ' me.myself!: Invalid
A reguláris kifejezés
^[A-Z0-9]([-!#$%&'.*+/=?^`{}|~\w])*(?<=[A-Z0-9])$
az alábbi táblázatban látható módon van definiálva.Minta Leírás ^
Kezdje el az egyezést a sztring elején. [A-Z0-9]
Tetszőleges numerikus vagy alfanumerikus karakternek felel meg. (Az összehasonlítás kis- és nagybetűket nem érzékelyítő.) ([-!#$%&'.*+/=?^`{}|~\w])*
Egyezik egy szójel vagy a következő karakterek nulla vagy több előfordulásával: -, !, #, $, %, &, ', ., *, +, /, =, ?, ^, ', {, }, |vagy ~. (?<=[A-Z0-9])
Keresse meg az előző karaktert, amelynek numerikusnak vagy alfanumerikusnak kell lennie. (Az összehasonlítás kis- és nagybetűket nem érzékelyítő.) $
Fejezd be a sztring végén lévő egyezést. A pozitív és negatív megjelenésről további információt a Csoportosítási szerkezetek című témakörben talál.
Kapcsolódó cikkek
Cím | Leírás |
---|---|
Visszakövetés | Tájékoztatást nyújt arról, hogy a reguláris kifejezések hogyan vonják vissza az ágakat az alternatív egyezések kereséséhez. |
Fordítás és újrafelhasználás | Információt nyújt a normál kifejezések összeállításáról és újrafelhasználásáról a teljesítmény növelése érdekében. |
.NET reguláris kifejezések | Áttekintést nyújt a reguláris kifejezések programozási nyelvi aspektusáról. |
A reguláris kifejezésobjektum-modell | A szokásos kifejezésosztályok használatát szemléltető információkat és kód példákat tartalmaz. |
Reguláris kifejezés nyelve – rövid útmutató | A szokásos kifejezések definiálásához használható karakterekről, operátorokról és szerkezetekről nyújt információt. |