Aracılığıyla paylaş


Dizeden alt dizeleri ayıklama

Bu makalede, bir dizenin bölümlerini ayıklamaya yönelik bazı farklı teknikler yer alır.

String.Split yöntemi

String.Split , bir dizeyi belirttiğiniz bir veya daha fazla sınırlayıcı karaktere göre bir alt dize grubuna ayırmanıza yardımcı olacak birkaç aşırı yükleme sağlar. Son sonuçtaki toplam alt dize sayısını sınırlamayı, alt dizelerdeki boşluk karakterlerini kırpmayı veya boş alt dizeleri hariç tutmayı seçebilirsiniz.

Aşağıdaki örneklerde üç farklı aşırı yüklemesi gösterilmektedir String.Split(). İlk örnek, herhangi bir ayırıcı karakter geçirmeden aşırı yüklemeyi çağırır Split(Char[]) . Sınırlayıcı karakter belirtmediğinizde, String.Split() dizeyi bölmek için boşluk karakterleri olan varsayılan sınırlayıcıları kullanır.

string s = "You win some. You lose some.";

string[] subs = s.Split();

foreach (string sub in subs)
{
    Console.WriteLine($"Substring: {sub}");
}

// This example produces the following output:
//
// Substring: You
// Substring: win
// Substring: some.
// Substring: You
// Substring: lose
// Substring: some.
Dim s As String = "You win some. You lose some."
Dim subs As String() = s.Split()

For Each substring As String In subs
    Console.WriteLine("Substring: {0}", substring)
Next

' This example produces the following output:
'
' Substring: You
' Substring: win
' Substring: some.
' Substring: You
' Substring: lose
' Substring: some.

Gördüğünüz gibi nokta karakterleri (.) iki alt dizeye eklenir. Nokta karakterlerini dışlamak istiyorsanız, nokta karakterini ek bir sınırlandırma karakteri olarak ekleyebilirsiniz. Sonraki örnekte bunun nasıl yapıldığını gösterilmektedir.

string s = "You win some. You lose some.";

string[] subs = s.Split(' ', '.');

foreach (string sub in subs)
{
    Console.WriteLine($"Substring: {sub}");
}

// This example produces the following output:
//
// Substring: You
// Substring: win
// Substring: some
// Substring:
// Substring: You
// Substring: lose
// Substring: some
// Substring:
Dim s As String = "You win some. You lose some."
Dim subs As String() = s.Split(" "c, "."c)

For Each substring As String In subs
    Console.WriteLine("Substring: {0}", substring)
Next

' This example produces the following output:
'
' Substring: You
' Substring: win
' Substring: some
' Substring:
' Substring: You
' Substring: lose
' Substring: some
' Substring:

Dönemler alt dizelerden silindi, ancak artık fazladan iki boş alt dize dahil edildi. Bu boş alt dize, sözcükle onu izleyen nokta arasındaki alt dizeyi temsil eder. Sonuçta elde edilen dizideki boş alt dizeleri atlamak için aşırı yüklemeyi çağırabilir Split(Char[], StringSplitOptions) ve parametresini options belirtebilirsinizStringSplitOptions.RemoveEmptyEntries.

string s = "You win some. You lose some.";
char[] separators = new char[] { ' ', '.' };

string[] subs = s.Split(separators, StringSplitOptions.RemoveEmptyEntries);

foreach (string sub in subs)
{
    Console.WriteLine($"Substring: {sub}");
}

// This example produces the following output:
//
// Substring: You
// Substring: win
// Substring: some
// Substring: You
// Substring: lose
// Substring: some
Dim s As String = "You win some. You lose some."
Dim separators As Char() = New Char() {" "c, "."c}
Dim subs As String() = s.Split(separators, StringSplitOptions.RemoveEmptyEntries)

For Each substring As String In subs
    Console.WriteLine("Substring: {0}", substring)
Next

' This example produces the following output:
'
' Substring: You
' Substring: win
' Substring: some
' Substring: You
' Substring: lose
' Substring: some

Normal ifadeler

Dizeniz sabit bir desene uygunsa, öğelerini ayıklamak ve işlemek için normal bir ifade kullanabilirsiniz. Örneğin, dizeler "sayı işlenen numarası" biçimindeyse, dizenin öğelerini ayıklamak ve işlemek için normal bir ifade kullanabilirsiniz. Bir örnek aşağıda verilmiştir:

String[] expressions = { "16 + 21", "31 * 3", "28 / 3",
                       "42 - 18", "12 * 7",
                       "2, 4, 6, 8" };
String pattern = @"(\d+)\s+([-+*/])\s+(\d+)";

foreach (string expression in expressions)
{
    foreach (System.Text.RegularExpressions.Match m in
    System.Text.RegularExpressions.Regex.Matches(expression, pattern))
    {
        int value1 = Int32.Parse(m.Groups[1].Value);
        int value2 = Int32.Parse(m.Groups[3].Value);
        switch (m.Groups[2].Value)
        {
            case "+":
                Console.WriteLine("{0} = {1}", m.Value, value1 + value2);
                break;
            case "-":
                Console.WriteLine("{0} = {1}", m.Value, value1 - value2);
                break;
            case "*":
                Console.WriteLine("{0} = {1}", m.Value, value1 * value2);
                break;
            case "/":
                Console.WriteLine("{0} = {1:N2}", m.Value, value1 / value2);
                break;
        }
    }
}

// The example displays the following output:
//       16 + 21 = 37
//       31 * 3 = 93
//       28 / 3 = 9.33
//       42 - 18 = 24
//       12 * 7 = 84
Dim expressions() As String = {"16 + 21", "31 * 3", "28 / 3",
                              "42 - 18", "12 * 7",
                              "2, 4, 6, 8"}

Dim pattern As String = "(\d+)\s+([-+*/])\s+(\d+)"
For Each expression In expressions
    For Each m As Match In Regex.Matches(expression, pattern)
        Dim value1 As Integer = Int32.Parse(m.Groups(1).Value)
        Dim value2 As Integer = Int32.Parse(m.Groups(3).Value)
        Select Case m.Groups(2).Value
            Case "+"
                Console.WriteLine("{0} = {1}", m.Value, value1 + value2)
            Case "-"
                Console.WriteLine("{0} = {1}", m.Value, value1 - value2)
            Case "*"
                Console.WriteLine("{0} = {1}", m.Value, value1 * value2)
            Case "/"
                Console.WriteLine("{0} = {1:N2}", m.Value, value1 / value2)
        End Select
    Next
Next

' The example displays the following output:
'       16 + 21 = 37
'       31 * 3 = 93
'       28 / 3 = 9.33
'       42 - 18 = 24
'       12 * 7 = 84

Normal ifade düzeni (\d+)\s+([-+*/])\s+(\d+) şöyle tanımlanır:

Desen Açıklama
(\d+) Bir veya daha fazla ondalık basamağı eşleştirin. Bu ilk yakalama grubudur.
\s+ Bir veya daha fazla boşluk karakteri eşleştirin.
([-+*/]) Aritmetik işleç işaretiyle (+, -, *veya /) eşleşir. Bu ikinci yakalama grubudur.
\s+ Bir veya daha fazla boşluk karakteri eşleştirin.
(\d+) Bir veya daha fazla ondalık basamağı eşleştirin. Bu, üçüncü yakalama grubudur.

Sabit bir karakter kümesi yerine desene göre bir dizeden alt dizeleri ayıklamak için normal ifade de kullanabilirsiniz. Bu, şu koşullardan herhangi biri oluştuğunda sık karşılaşılan bir senaryodur:

  • Bir veya daha fazla sınırlayıcı karakteri her zaman örnekte sınırlayıcı String olarak çalışmaz.

  • Sınırlayıcı karakterlerin sırası ve sayısı değişken veya bilinmiyor.

Örneğin, Split (yeni satır) karakter sayısı \n değişken olduğundan ve her zaman sınırlayıcı olarak hizmet vermediğinden yöntemi aşağıdaki dizeyi bölmek için kullanılamaz.

[This is captured\ntext.]\n\n[\n[This is more captured text.]\n]
\n[Some more captured text:\n   Option1\n   Option2][Terse text.]

Aşağıdaki örnekte gösterildiği gibi normal bir ifade bu dizeyi kolayca bölebilir.

String input = "[This is captured\ntext.]\n\n[\n" +
               "[This is more captured text.]\n]\n" +
               "[Some more captured text:\n   Option1" +
               "\n   Option2][Terse text.]";
String pattern = @"\[([^\[\]]+)\]";
int ctr = 0;

foreach (System.Text.RegularExpressions.Match m in
   System.Text.RegularExpressions.Regex.Matches(input, pattern))
{
    Console.WriteLine("{0}: {1}", ++ctr, m.Groups[1].Value);
}

// The example displays the following output:
//       1: This is captured
//       text.
//       2: This is more captured text.
//       3: Some more captured text:
//          Option1
//          Option2
//       4: Terse text.
Dim input As String = String.Format("[This is captured{0}text.]" +
                                  "{0}{0}[{0}[This is more " +
                                  "captured text.]{0}{0}" +
                                  "[Some more captured text:" +
                                  "{0}   Option1" +
                                  "{0}   Option2][Terse text.]",
                                  vbCrLf)
Dim pattern As String = "\[([^\[\]]+)\]"
Dim ctr As Integer = 0
For Each m As Match In Regex.Matches(input, pattern)
    ctr += 1
    Console.WriteLine("{0}: {1}", ctr, m.Groups(1).Value)
Next

' The example displays the following output:
'       1: This is captured
'       text.
'       2: This is more captured text.
'       3: Some more captured text:
'          Option1
'          Option2
'       4: Terse text.

Normal ifade düzeni \[([^\[\]]+)\] şöyle tanımlanır:

Desen Açıklama
\[ Bir açma ayracı eşleştirin.
([^\[\]]+) Açma veya kapatma köşeli ayracı olmayan herhangi bir karakteri bir veya daha fazla kez eşleştirin. Bu ilk yakalama grubudur.
\] Bir kapanış köşeli ayracı eşleştirin.

Regex.Split yöntemi, sabit karakter kümesi yerine bir dizeyi normal ifade desenine göre bölmesi dışında neredeyse ile aynıdırString.Split. Örneğin, aşağıdaki örnek, çeşitli kısa çizgi ve diğer karakter bileşimleriyle sınırlandırılmış alt dizeler içeren bir dizeyi bölmek için yöntemini kullanır Regex.Split .

String input = "abacus -- alabaster - * - atrium -+- " +
               "any -*- actual - + - armoire - - alarm";
String pattern = @"\s-\s?[+*]?\s?-\s";
String[] elements = System.Text.RegularExpressions.Regex.Split(input, pattern);

foreach (string element in elements)
    Console.WriteLine(element);

// The example displays the following output:
//       abacus
//       alabaster
//       atrium
//       any
//       actual
//       armoire
//       alarm
Dim input As String = "abacus -- alabaster - * - atrium -+- " +
                    "any -*- actual - + - armoire - - alarm"
Dim pattern As String = "\s-\s?[+*]?\s?-\s"
Dim elements() As String = Regex.Split(input, pattern)
For Each element In elements
    Console.WriteLine(element)
Next

' The example displays the following output:
'       abacus
'       alabaster
'       atrium
'       any
'       actual
'       armoire
'       alarm

Normal ifade düzeni \s-\s?[+*]?\s?-\s şöyle tanımlanır:

Desen Açıklama
\s- Boşluk karakterini ve ardından kısa çizgiyi eşleştirin.
\s? Sıfır veya bir beyaz boşluk karakterini eşleştirin.
[+*]? + veya * karakterinin sıfır veya bir oluşumunu eşleştirin.
\s? Sıfır veya bir beyaz boşluk karakterini eşleştirin.
-\s Kısa çizgi ve ardından boşluk karakteri eşleştirin.

String.IndexOf ve String.Substring yöntemleri

Bir dizedeki tüm alt dizelerle ilgilenmiyorsanız, eşleşmenin başladığı dizini döndüren dize karşılaştırma yöntemlerinden biriyle çalışmayı tercih edebilirsiniz. Ardından istediğiniz alt dizeyi Substring ayıklamak için yöntemini çağırabilirsiniz. Dize karşılaştırma yöntemleri şunlardır:

  • IndexOf, bir dize örneğindeki bir karakterin veya dizenin ilk oluşumunun sıfır tabanlı dizinini döndürür.

  • IndexOfAny, bir karakter dizisindeki herhangi bir karakterin ilk geçtiği geçerli dize örneğinde sıfır tabanlı dizini döndürür.

  • LastIndexOf, bir dize örneğindeki bir karakterin veya dizenin son oluşumunun sıfır tabanlı dizinini döndürür.

  • LastIndexOfAny, bir karakter dizisindeki herhangi bir karakterin son oluşumunun geçerli dize örneğinde sıfır tabanlı bir dizin döndürür.

Aşağıdaki örnek, dizedeki IndexOf dönemleri bulmak için yöntemini kullanır. Ardından tam cümleler döndürmek için yöntemini kullanır Substring .

String s = "This is the first sentence in a string. " +
               "More sentences will follow. For example, " +
               "this is the third sentence. This is the " +
               "fourth. And this is the fifth and final " +
               "sentence.";
var sentences = new List<String>();
int start = 0;
int position;

// Extract sentences from the string.
do
{
    position = s.IndexOf('.', start);
    if (position >= 0)
    {
        sentences.Add(s.Substring(start, position - start + 1).Trim());
        start = position + 1;
    }
} while (position > 0);

// Display the sentences.
foreach (var sentence in sentences)
    Console.WriteLine(sentence);

// The example displays the following output:
//       This is the first sentence in a string.
//       More sentences will follow.
//       For example, this is the third sentence.
//       This is the fourth.
//       And this is the fifth and final sentence.
    Dim input As String = "This is the first sentence in a string. " +
                        "More sentences will follow. For example, " +
                        "this is the third sentence. This is the " +
                        "fourth. And this is the fifth and final " +
                        "sentence."
    Dim sentences As New List(Of String)
    Dim start As Integer = 0
    Dim position As Integer

    ' Extract sentences from the string.
    Do
        position = input.IndexOf("."c, start)
        If position >= 0 Then
            sentences.Add(input.Substring(start, position - start + 1).Trim())
            start = position + 1
        End If
    Loop While position > 0

    ' Display the sentences.
    For Each sentence In sentences
        Console.WriteLine(sentence)
    Next
End Sub

' The example displays the following output:
'       This is the first sentence in a string.
'       More sentences will follow.
'       For example, this is the third sentence.
'       This is the fourth.
'       And this is the fifth and final sentence.

Ayrıca bkz.