Dela via


Extrahera delsträngar från en sträng

Den här artikeln beskriver några olika tekniker för att extrahera delar av en sträng.

  • Använd metoden Dela när de delsträngar du vill ha avgränsas med ett känt avgränsande tecken (eller tecken).
  • Reguljära uttryck är användbara när strängen överensstämmer med ett fast mönster.
  • Använd metoderna IndexOf och Substring tillsammans när du inte vill extrahera alla delsträngar i en sträng.

String.Split-metod

String.Split innehåller en handfull överlagringar som hjälper dig att dela upp en sträng i en grupp med understrängar baserat på ett eller flera avgränsande tecken som du anger. Du kan välja att begränsa det totala antalet delsträngar i slutresultatet, trimma blankstegstecken från delsträngar eller exkludera tomma delsträngar.

I följande exempel visas tre olika överlagringar av String.Split(). I det första exemplet anropas överbelastningen Split(Char[]) utan att några avgränsartecken skickas. När du inte anger några avgränsande tecken String.Split() använder du standardavgränsare, som är blankstegstecken, för att dela upp strängen.

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.

Som du ser inkluderas periodtecken (.) i två av delsträngarna. Om du vill undanta periodtecken kan du lägga till periodtecknet som ytterligare ett avgränsande tecken. I nästa exempel visas hur du gör detta.

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:

Perioderna är borta från delsträngarna, men nu har två extra tomma delsträngar inkluderats. Dessa tomma delsträngar representerar delsträngen mellan ordet och den period som följer det. Om du vill utelämna tomma delsträngar från den resulterande matrisen kan du anropa överlagringen Split(Char[], StringSplitOptions) och ange StringSplitOptions.RemoveEmptyEntries för parametern options .

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

Reguljära uttryck

Om strängen överensstämmer med ett fast mönster kan du använda ett reguljärt uttryck för att extrahera och hantera dess element. Om strängar till exempel har formatet "number operand number" kan du använda ett reguljärt uttryck för att extrahera och hantera strängens element. Här är ett exempel:

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

Mönster för (\d+)\s+([-+*/])\s+(\d+) reguljära uttryck definieras så här:

Mönster beskrivning
(\d+) Matcha en eller flera decimaler. Det här är den första insamlingsgruppen.
\s+ Matcha ett eller flera blankstegstecken.
([-+*/]) Matcha ett aritmetikoperatortecken (+, -, *eller /). Det här är den andra insamlingsgruppen.
\s+ Matcha ett eller flera blankstegstecken.
(\d+) Matcha en eller flera decimaler. Det här är den tredje insamlingsgruppen.

Du kan också använda ett reguljärt uttryck för att extrahera delsträngar från en sträng baserat på ett mönster i stället för en fast uppsättning tecken. Det här är ett vanligt scenario när något av dessa villkor inträffar:

  • Ett eller flera av avgränsartecken fungerar inte alltid som avgränsare i instansen String .

  • Sekvensen och antalet avgränsartecken är variabel eller okänd.

Metoden kan till exempel Split inte användas för att dela upp följande sträng, eftersom antalet \n (nya) tecken är variabel och de inte alltid fungerar som avgränsare.

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

Ett reguljärt uttryck kan enkelt dela upp strängen, vilket visas i följande exempel.

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.

Mönster för \[([^\[\]]+)\] reguljära uttryck definieras så här:

Mönster beskrivning
\[ Matcha en inledande hakparentes.
([^\[\]]+) Matcha alla tecken som inte är en öppning eller en avslutande hakparentes en eller flera gånger. Det här är den första insamlingsgruppen.
\] Matcha en avslutande hakparentes.

Metoden Regex.Split är nästan identisk String.Splitmed , förutom att den delar en sträng baserat på ett reguljärt uttrycksmönster i stället för en fast teckenuppsättning. I följande exempel används Regex.Split till exempel metoden för att dela upp en sträng som innehåller delsträngar avgränsade med olika kombinationer av bindestreck och andra tecken.

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

Mönster för \s-\s?[+*]?\s?-\s reguljära uttryck definieras så här:

Mönster beskrivning
\s- Matcha ett blankstegstecken följt av ett bindestreck.
\s? Matcha noll eller ett blankstegstecken.
[+*]? Matcha noll eller en förekomst av tecknet + eller * .
\s? Matcha noll eller ett blankstegstecken.
-\s Matcha ett bindestreck följt av ett blankstegstecken.

String.IndexOf- och String.Substring-metoder

Om du inte är intresserad av alla delsträngar i en sträng kanske du föredrar att arbeta med någon av de strängjämförelsemetoder som returnerar indexet där matchningen börjar. Du kan sedan anropa Substring metoden för att extrahera den delsträng som du vill använda. Metoderna för strängjämförelse omfattar:

  • IndexOf, som returnerar det nollbaserade indexet för den första förekomsten av ett tecken eller en sträng i en stränginstans.

  • IndexOfAny, som returnerar det nollbaserade indexet i den aktuella stränginstansen av den första förekomsten av ett tecken i en teckenmatris.

  • LastIndexOf, som returnerar det nollbaserade indexet för den senaste förekomsten av ett tecken eller en sträng i en stränginstans.

  • LastIndexOfAny, som returnerar ett nollbaserat index i den aktuella stränginstansen av den senaste förekomsten av ett tecken i en teckenmatris.

I följande exempel används IndexOf metoden för att hitta perioderna i en sträng. Den använder Substring sedan metoden för att returnera fullständiga meningar.

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.

Se även