Aracılığıyla paylaş


Normal ifade davranışının ayrıntıları

.NET normal ifade altyapısı, Perl, Python, Emacs ve Tcl tarafından kullanılan gibi geleneksel Bir Nondeterministic Finite Automaton (NFA) altyapısını içeren bir geri izleme normal ifade eşleştiricisidir. Bu, awk, egrep veya lex'te bulunanlar gibi daha hızlı, ancak daha sınırlı, saf normal ifade Deterministic Finite Automaton (DFA) altyapılarından ayırır. Bu, standartlaştırılmış ancak daha yavaş POSIX NFA'larından da ayırt eder. Aşağıdaki bölümde üç normal ifade altyapısı türü açıklanır ve .NET'teki normal ifadelerin neden geleneksel bir NFA altyapısı kullanılarak uygulandığı açıklanmaktadır.

NFA altyapısının avantajları

DFA altyapıları desen eşleştirmesi gerçekleştirdiğinde, işleme sırası giriş dizesi tarafından yönlendirilir. Altyapı giriş dizesinin başında başlar ve sonraki karakterin normal ifade deseni ile eşleşip eşleşmediğini belirlemek için sıralı olarak devam eder. Mümkün olan en uzun dizeyle eşleşmeyi garanti edebilir. Aynı karakteri hiçbir zaman iki kez test etmedikleri için DFA altyapıları geri izlemeyi desteklemez. Ancak, bir DFA altyapısı yalnızca sonlu durum içerdiği için, bir deseni geri başvurularla eşleştiremez ve açık bir genişletme oluşturmadığından alt ifadeleri yakalayamaz.

DFA altyapılarından farklı olarak, geleneksel NFA altyapıları desen eşleştirmesi gerçekleştirdiğinde, işleme sırası normal ifade deseni tarafından yönlendirilir. Belirli bir dil öğesini işlerken altyapı doyumsuz eşleştirme kullanır; yani, giriş dizesini mümkün olduğunca eşleştirir. Ancak, bir alt ifadeyi başarıyla eşleştirdikten sonra durumunu da kaydeder. Bir eşleşme sonunda başarısız olursa, altyapı ek eşleşmeleri deneyebilmesi için kaydedilmiş bir duruma geri dönebilir. Normal ifadedeki sonraki dil öğelerinin de eşleşmesi için başarılı bir alt ifade eşleşmesini bırakma işlemi geri izleme olarak bilinir. NFA altyapıları, normal ifadenin tüm olası genişletmelerini belirli bir sırada test etmek ve ilk eşleşmeyi kabul etmek için geri izlemeyi kullanır. Geleneksel bir NFA altyapısı başarılı bir eşleşme için normal ifadenin belirli bir genişletmesini oluşturacağından, alt ifade eşleşmelerini ve eşleşen geri başvurularını yakalayabilir. Ancak, geleneksel bir NFA geri izlemesi nedeniyle, farklı yollar üzerinden duruma ulaşırsa aynı durumu birden çok kez ziyaret edebilir. Sonuç olarak, en kötü durumda üssel olarak yavaş çalışabilir. Geleneksel bir NFA altyapısı bulduğu ilk eşleşmeyi kabul ettiğinden, diğer (muhtemelen daha uzun) eşleşmeleri keşfedilmemiş olarak bırakabilir.

POSIX NFA motorları geleneksel NFA altyapılarına benzer, ancak mümkün olan en uzun eşleşmeyi bulduklarını garanti edene kadar geri dönüş yapmaya devam ederler. Sonuç olarak, POSIX NFA altyapısı geleneksel bir NFA altyapısından daha yavaştır ve POSIX NFA altyapısını kullandığınızda, geri izleme aramasının sırasını değiştirerek daha uzun bir altyapıya kıyasla daha kısa bir eşleşmeyi tercih edemezsiniz.

Geleneksel NFA altyapıları, DFA veya POSIX NFA altyapılarından daha fazla dize eşleştirme denetimi sunduğundan programcılar tarafından tercih edilir. En kötü durumda yavaş çalışsalar da, belirsizlikleri azaltan ve geri izlemeyi sınırlayan desenler kullanarak onları doğrusal veya polinomsal zamanda eşleşmeleri bulmaya yönlendirebilirsiniz. Başka bir deyişle, NFA motorları güç ve esneklik için performansı takas etse de, normal bir ifade iyi yazılmışsa ve geri izlemenin performansı üstel olarak düşüren durumlardan kaçınıyorsa çoğu durumda kabul edilebilir performans sunar.

Not

Aşırı geri izlemenin neden olduğu performans cezası ve bunları geçici olarak çözmek için normal bir ifade oluşturmanın yolları hakkında bilgi için bkz . Geri izleme.

.NET altyapısı özellikleri

Geleneksel bir NFA altyapısının avantajlarından yararlanmak için .NET normal ifade altyapısı, programcıların geri izleme altyapısını yönlendirmesini sağlayan eksiksiz bir yapı kümesi içerir. Bu yapılar, eşleşmeleri daha hızlı bulmak veya belirli genişletmeleri diğerlerine tercih etmek için kullanılabilir.

.NET normal ifade altyapısının diğer özellikleri şunlardır:

  • Tembel niceleyiciler: ??, *?, +?, {n,m}?. Bu yapılar, geri izleme altyapısına önce en az yineleme sayısını aramasını söyler. Buna karşılık, sıradan doyumsuz niceleyiciler önce en fazla tekrar sayısıyla eşleşmeye çalışır. Aşağıdaki örnekte ikisi arasındaki fark gösterilmektedir. Normal ifade, bir sayı ile biten tümceyle eşleşir ve yakalama grubu bu sayıyı ayıklamaya yöneliktir. Normal ifade, normal ifade .+(\d+)\. altyapısının sayının yalnızca son rakamını yakalamasına neden olan doyumsuz niceleyiciyi .+içerir. Buna karşılık, normal ifade .+?(\d+)\. gecikmeli niceleyiciyi .+?içerir ve bu da normal ifade altyapısının tüm sayıyı yakalamasına neden olur.

    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
    

    Bu normal ifadenin doyumsuz ve yavaş sürümleri aşağıdaki tabloda gösterildiği gibi tanımlanır:

    Desen Açıklama
    .+ (doyumsuz niceleyici) Herhangi bir karakterin en az bir oluşumunu eşleştirin. Bu, normal ifade altyapısının dizenin tamamıyla eşleşmesine ve ardından desenin geri kalanıyla eşleşecek şekilde geri dönmesine neden olur.
    .+? (gecikmeli niceleyici) Herhangi bir karakterin en az bir oluşumunu eşleştirin, ancak mümkün olduğunca azını eşleştirin.
    (\d+) En az bir sayısal karakter eşleştirin ve ilk yakalama grubuna atayın.
    \. Bir dönemi eşleştirin.

    Yavaş niceleyiciler hakkında daha fazla bilgi için bkz . Niceleyiciler.

  • Pozitif lookahead: (?=subexpression). Bu özellik, bir alt ifadeyi eşleştirdikten sonra geri izleme altyapısının metinde aynı noktaya dönmesini sağlar. Aynı konumdan başlayan birden çok deseni doğrulayarak metin genelinde arama için kullanışlıdır. Ayrıca altyapının eşleşen metne alt dize eklemeden eşleşmenin sonunda bir alt dize olduğunu doğrulamasını sağlar. Aşağıdaki örnek, noktalama işaretleri tarafından takip edilmeyen bir cümledeki sözcükleri ayıklamak için pozitif lookahead kullanır.

    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
    

    Normal ifade \b[A-Z]+\b(?=\P{P}) aşağıdaki tabloda gösterildiği gibi tanımlanır.

    Desen Açıklama
    \b Bir sözcük sınırında eşleşmeye başla.
    [A-Z]+ Herhangi bir alfabetik karakteri bir veya daha fazla kez eşleştirin. Regex.Matches yöntemi seçeneğiyle RegexOptions.IgnoreCase çağrıldığından, karşılaştırma büyük/küçük harfe duyarlı değildir.
    \b Eşlemeyi bir sözcük sınırında sonlandır.
    (?=\P{P}) Sonraki karakterin noktalama işareti olup olmadığını belirlemek için ileriye bakın. Değilse, eşleşme başarılı olur.

    Pozitif lookahead onayları hakkında daha fazla bilgi için bkz . Gruplandırma Yapıları.

  • Negatif lookahead: (?!subexpression). Bu özellik, yalnızca bir alt ifadenin eşleşmemesi durumunda ifadeyle eşleşme özelliğini ekler. Bu, aramayı ayıklamak için güçlüdür, çünkü dahil edilmesi gereken durumlar için bir ifadeden daha ortadan kaldırılması gereken bir servis talebi için ifade sağlamak genellikle daha kolaydır. Örneğin, "non" ile başlamayan sözcükler için ifade yazmak zordur. Aşağıdaki örnek, bunları dışlamak için negatif lookahead kullanır.

    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
    

    Normal ifade deseni \b(?!non)\w+\b aşağıdaki tabloda gösterildiği gibi tanımlanır.

    Desen Açıklama
    \b Bir sözcük sınırında eşleşmeye başla.
    (?!non) Geçerli dizenin "non" ile başlamadığından emin olmak için ileriye bakın. Varsa, eşleşme başarısız olur.
    (\w+) Bir veya daha fazla sözcük karakteri eşleştir.
    \b Eşlemeyi bir sözcük sınırında sonlandır.

    Olumsuz lookahead onayları hakkında daha fazla bilgi için bkz . Gruplandırma Yapıları.

  • Koşullu değerlendirme: (?(ifade)evet|hayır) ve (?(ad)evet|hayır), burada ifade eşleşecek bir alt ifadedir, ad bir yakalama grubunun adıdır, evet ifade eşleşirse eşleşecek dizedir veya ad geçerli, boş olmayan bir yakalanan grupsa ve if ifadesiyle eşleşecek alt ifade hayır eşleşmedi veya ad geçerli, boş olmayan bir yakalanan grup değil. Bu özellik, önceki bir alt ifade eşleşmesinin sonucuna veya sıfır genişlikli onay işleminin sonucuna bağlı olarak altyapının birden fazla alternatif desen kullanarak arama yapmasına olanak tanır. Bu, önceki bir alt ifadenin eşleşip eşleşmediğine bağlı olarak bir alt ifadeyi eşleştirmeye izin veren daha güçlü bir geri başvuru biçimi sağlar. Aşağıdaki örnekteki normal ifade, hem genel hem de iç kullanıma yönelik paragraflarla eşleşir. Yalnızca iç kullanım için tasarlanan paragraflar bir <PRIVATE> etiketle başlar. Normal ifade düzeni ^(?<Pvt>\<PRIVATE\>\s)?(?(Pvt)((\w+\p{P}?\s)+)|((\w+\p{P}?\s)+))\r?$ , genel ve iç kullanım için hedeflenen paragrafların içeriğini yakalama gruplarını ayırmak için koşullu değerlendirme kullanır. Bu paragraflar daha sonra farklı şekilde işlenebilir.

    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.
    

    Normal ifade deseni aşağıdaki tabloda gösterildiği gibi tanımlanır.

    Desen Açıklama
    ^ Eşleşmeye satırın başında başlayın.
    (?<Pvt>\<PRIVATE\>\s)? Dizenin <PRIVATE> sıfır veya bir oluşumunu ve ardından boşluk karakterini eşleştirin. Eşleşmeyi adlı bir yakalama grubuna atayın Pvt.
    (?(Pvt)((\w+\p{P}?\s)+) Pvt Yakalama grubu varsa, bir veya daha fazla sözcük karakterinin bir veya daha fazla örneğini, ardından sıfır veya bir noktalama ayırıcısı ve ardından boşluk karakteriyle eşleştirin. Alt dizeyi ilk yakalama grubuna atayın.
    |((\w+\p{P}?\s)+)) Pvt Yakalama grubu yoksa, bir veya daha fazla sözcük karakterinin bir veya birden çok örneğini, ardından sıfır veya bir noktalama ayırıcısı ve ardından boşluk karakteriyle eşleştirin. Alt dizeyi üçüncü yakalama grubuna atayın.
    \r?$ Satırın sonunu veya dizenin sonunu eşleştirin.

    Koşullu değerlendirme hakkında daha fazla bilgi için bkz . Değişiklik Yapıları.

  • Grup tanımlarını dengeleme: (?<name1-name2>subexpression.) Bu özellik, normal ifade altyapısının parantezler veya açma ve kapatma köşeli ayraçları gibi iç içe yerleştirilmiş yapıları izlemesine olanak tanır. Bir örnek için bkz . Yapıları Gruplandırma.

  • Atomik gruplar: (?>alt ifade). Bu özellik, bir alt ifadenin, ifadeyi içeren ifadeden bağımsız olarak çalışıyor gibi alt ifadenin yalnızca bu alt ifade için bulunan ilk eşleşmeyle eşleşip eşleşmediğini garanti etmesini sağlar. Bu yapıyı kullanmazsanız, büyük ifadeden yapılan geri izleme aramaları bir alt ifadenin davranışını değiştirebilir. Örneğin, normal ifade (a+)\w bir veya daha fazla "a" karakteriyle ve "a" karakterlerinin sırasını izleyen bir sözcük karakteriyle eşleşir ve "a" karakter sırasını ilk yakalama grubuna atar. Ancak, giriş dizesinin son karakteri de bir "a" ise, dil öğesiyle \w eşleştirilir ve yakalanan gruba dahil edilmez.

    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
    

    Normal ifade ((?>a+))\w bu davranışı engeller. Ardışık tüm "a" karakterleri geri izleme olmadan eşleştirildiğinden, ilk yakalama grubu ardışık tüm "a" karakterleri içerir. "a" karakterlerinin ardından "a" dışında en az bir karakter daha yoksa, eşleşme başarısız olur.

    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
    

    Atomik gruplar hakkında daha fazla bilgi için bkz . Gruplandırma Yapıları.

  • Bir sınıf oluşturucu veya statik örnek eşleştirme yöntemine Regex seçeneği sağlanarak RegexOptions.RightToLeft belirtilen sağdan sola eşleştirme. Bu özellik, soldan sağa yerine sağdan sola arama yaparken veya desenin sol yerine sağ kısmında eşleşme başlatmanın daha verimli olduğu durumlarda kullanışlıdır. Aşağıdaki örnekte gösterildiği gibi, sağdan sola eşleştirmenin kullanılması doyumsuz niceleyicilerin davranışını değiştirebilir. Örnek, bir sayı ile biten bir tümce için iki arama yürütür. Doyumsuz niceleyiciyi + kullanan soldan sağa arama, tümcedeki altı basamakla eşleşirken, sağdan sola arama altı basamakla da eşleşir. Normal ifade deseninin açıklaması için, bu bölümün önceki bölümlerinde yer alan gecikmeli niceleyicileri gösteren örne bakın.

    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
    

    Sağdan sola eşleştirme hakkında daha fazla bilgi için bkz . Normal İfade Seçenekleri.

  • Pozitif ve negatif lookbehind: (?<=pozitif görünüm için alt) ifade ve(?<! negatif görünüm için alt ifade). Bu özellik, bu konunun önceki bölümlerinde ele alınan lookahead'e benzer. Normal ifade altyapısı tam sağdan sola eşleştirmeye izin verdiğinden, normal ifadeler kısıtlanmamış görünümlere izin verir. İç içe alt ifade bir dış ifadenin üst kümesi olduğunda niceleyicilerin iç içe geçmemesi için pozitif ve negatif görünüm de kullanılabilir. Bu tür iç içe niceleyicilere sahip normal ifadeler genellikle düşük performans sunar. Örneğin, aşağıdaki örnek bir dizenin alfasayısal karakterle başlayıp bittiğini ve dizedeki diğer karakterlerin daha büyük bir alt kümeden biri olduğunu doğrular. E-posta adreslerini doğrulamak için kullanılan normal ifadenin bir bölümünü oluşturur; daha fazla bilgi için bkz . Nasıl yapılır: Dizelerin Geçerli E-posta Biçiminde Olduğunu Doğrulama.

    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
    

    Normal ifade ^[A-Z0-9]([-!#$%&'.*+/=?^`{}|~\w])*(?<=[A-Z0-9])$ aşağıdaki tabloda gösterildiği gibi tanımlanır.

    Desen Açıklama
    ^ Eşleşmeye dizenin başında başlayın.
    [A-Z0-9] Herhangi bir sayısal veya alfasayısal karakteri eşleştirin. (Karşılaştırma büyük/küçük harfe duyarlı değildir.)
    ([-!#$%&'.*+/=?^`{}|~\w])* Herhangi bir sözcük karakterinin veya şu karakterlerden herhangi birinin sıfır veya daha fazla örneğini eşleştirin: -, !, #, $, %, &, ', ., *, +, /, =, ?, ^, ', {, }, |veya ~.
    (?<=[A-Z0-9]) Sayısal veya alfasayısal olması gereken önceki karakterin arkasına bakın. (Karşılaştırma büyük/küçük harfe duyarlı değildir.)
    $ Dizenin sonunda eşleşmeyi sonlandırın.

    Pozitif ve negatif görünüm hakkında daha fazla bilgi için bkz . Yapıları Gruplandırma.

Ünvan Açıklama
Geri Dönüş Alternatif eşleşmeleri bulmak için normal ifade geri izleme dalları hakkında bilgi sağlar.
Derleme ve Yeniden Kullanma Performansı artırmak için normal ifadeleri derleme ve yeniden kullanımı hakkında bilgi sağlar.
.NET Normal İfadeleri Normal ifadelerin programlama dili yönüne genel bir bakış sağlar.
Normal İfade Nesne Modeli Normal ifade sınıflarının nasıl kullanılacağını gösteren bilgi ve kod örnekleri sağlar.
Normal İfade Dili - Hızlı Başvuru Normal ifadeleri tanımlamak için kullanabileceğiniz karakter, işleç ve yapı kümesi hakkında bilgi sağlar.

Başvuru