Extrahieren von Teilzeichenfolgen aus einer Zeichenfolge
In diesem Artikel werden verschiedene Techniken zum Extrahieren von Teilen einer Zeichenfolge behandelt.
- Verwenden Sie die Split-Methode, wenn die gewünschten Teilzeichenfolgen durch ein bekanntes Trennzeichen (oder mehrere) getrennt sind.
- Reguläre Ausdrücke sind nützlich, wenn die Zeichenfolge einem festen Muster entspricht.
- Verwenden Sie die Methoden IndexOf und Substring in Verbindung miteinander, wenn Sie nicht alle Teilzeichenfolgen in einer Zeichenfolge extrahieren möchten.
String.Split-Methode
String.Split bietet mehrere Überladungen, die Ihnen helfen, eine Zeichenfolge in eine Gruppe von Teilzeichenfolgen zu zerlegen, die auf einem oder mehreren von Ihnen angegebenen Trennzeichen basieren. Sie können die Gesamtanzahl der Teilzeichenfolgen im Endergebnis begrenzen, Leerzeichen aus Teilzeichenfolgen entfernen oder leere Teilzeichenfolgen ausschließen.
Die folgenden Beispiele zeigen drei verschiedene Überladungen von String.Split()
. Im ersten Beispiel wird die Überladung Split(Char[]) ohne Übergabe von Trennzeichen aufgerufen. Wenn Sie keine Trennzeichen angeben, verwendet String.Split()
Standardtrennzeichen, bei denen es sich um Leerzeichen handelt, um die Zeichenfolge aufzuteilen.
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.
Wie Sie sehen können, sind die Punktzeichen (.
) in zwei der Teilzeichenfolgen enthalten. Wenn Sie die Punktzeichen ausschließen möchten, können Sie das Punktzeichen als zusätzliches Trennzeichen hinzufügen. Im nächsten Beispiel wird gezeigt, wie dies geschieht.
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:
Die Punkte sind aus den Teilzeichenfolgen verschwunden, aber jetzt wurden zwei zusätzliche leere Teilzeichenfolgen eingefügt. Diese leere Teilzeichenfolge stellt die Teilzeichenfolge zwischen dem Wort und dem darauf folgenden Punkt dar. Um leere Teilzeichenfolgen aus dem resultierenden Array auszuschließen, können Sie die Überladung Split(Char[], StringSplitOptions) aufrufen und StringSplitOptions.RemoveEmptyEntries für den Parameter options
angeben.
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
Reguläre Ausdrücke
Wenn Ihre Zeichenfolge mit einem festen Muster übereinstimmt, können Sie mit einem regulären Ausdruck dessen Elemente extrahieren und verarbeiten. Wenn Zeichenfolgen zum Beispiel die Form „Zahl Operand Zahl“ haben, können Sie einen regulären Ausdruck verwenden, um die Zeichenfolge zu extrahieren und die Elemente der Zeichenfolge zu verarbeiten. Ein Beispiel:
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
Das Muster für reguläre Ausdrücke, (\d+)\s+([-+*/])\s+(\d+)
, ist so definiert:
Muster | Beschreibung |
---|---|
(\d+) |
Entsprechung für mindestens eine Dezimalstelle finden. Dies ist die erste Erfassungsgruppe. |
\s+ |
Übereinstimmung mit mindestens einem Leerzeichen finden. |
([-+*/]) |
Übereinstimmung mit dem Zeichen eines arithmetischen Operators (+, -, * oder /) finden. Dies ist die zweite Erfassungsgruppe. |
\s+ |
Übereinstimmung mit mindestens einem Leerzeichen finden. |
(\d+) |
Entsprechung für mindestens eine Dezimalstelle finden. Dies ist die dritte Erfassungsgruppe. |
Sie können auch einen regulären Ausdruck verwenden, um Teilzeichenfolgen aus einer Zeichenfolge zu extrahieren, die auf einem Muster statt auf einem festen Satz von Zeichen basieren. Dies ist ein gängiges Szenario, wenn eine der folgenden Bedingungen zutrifft:
Mindestens eines der Trennzeichen dient in der String-Instanz nicht immer als Trennzeichen.
Sequenz und Anzahl der Trennzeichen sind variabel oder unbekannt.
Beispielsweise kann die Split-Methode nicht verwendet werden, um die folgende Zeichenfolge aufzuteilen, da die Anzahl von \n
-Zeichen (Zeilenvorschub) variabel ist und sie nicht immer als Trennzeichen dienen.
[This is captured\ntext.]\n\n[\n[This is more captured text.]\n]
\n[Some more captured text:\n Option1\n Option2][Terse text.]
Ein regulärer Ausdruck kann diese Zeichenfolge problemlos aufteilen, wie im folgenden Beispiel gezeigt.
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.
Das Muster für reguläre Ausdrücke, \[([^\[\]]+)\]
, ist so definiert:
Muster | Beschreibung |
---|---|
\[ |
Übereinstimmung mit einer öffnenden geschweiften Klammer finden. |
([^\[\]]+) |
Einmal oder mehrmals eine Übereinstimmung mit einem beliebigen Zeichen finden, das keine öffnende oder schließende eckige Klammer ist. Dies ist die erste Erfassungsgruppe. |
\] |
Übereinstimmung mit einer schließenden geschweiften Klammer finden. |
Die Methode Regex.Split ist fast identisch mit String.Split, außer dass sie eine Zeichenfolge auf Grundlage eines Musters regulärer Ausdrücke anstelle eines festen Satzes von Zeichen aufteilt. Im folgenden Beispiel wird beispielsweise die Regex.Split-Methode verwendet, um eine Zeichenfolge mit Teilzeichenfolgen zu teilen, die durch verschiedene Kombinationen von Bindestrichen und anderen Zeichen voneinander getrennt sind.
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
Das Muster für reguläre Ausdrücke, \s-\s?[+*]?\s?-\s
, ist so definiert:
Muster | Beschreibung |
---|---|
\s- |
Übereinstimmung mit einem Leerzeichen gefolgt von einem Bindestrich finden. |
\s? |
Übereinstimmung mit keinem oder einem Leerzeichen. |
[+*]? |
Übereinstimmung mit null oder einem Vorkommen von entweder dem Zeichen + oder * finden. |
\s? |
Übereinstimmung mit keinem oder einem Leerzeichen. |
-\s |
Übereinstimmung mit einem Bindestrich gefolgt von einem Leerzeichen finden. |
Die Methoden String.IndexOf und String.Substring
Wenn Sie nicht an allen Teilzeichenfolgen in einer Zeichenfolge interessiert sind, können Sie auch mit einer der Methoden zum Vergleichen von Zeichenfolgen arbeiten, die den Index zurückgibt, bei dem die Übereinstimmung beginnt. Sie können dann die Substring-Methode aufrufen, um die gewünschte Teilzeichenfolge zu extrahieren. Es gibt die folgenden Methoden zum Vergleichen von Zeichenfolgen:
IndexOf, die den auf null basierenden Index des ersten Vorkommens eines Zeichens oder einer Zeichenfolge in einer Zeichenfolgeninstanz zurückgibt.
IndexOfAny, die den auf null basierenden Index in der aktuellen Zeichenfolgeninstanz beim ersten Vorkommen eines beliebigen Zeichens in einem Zeichenarray zurückgibt.
LastIndexOf, die den auf null basierenden Index des letzten Vorkommens eines Zeichens oder einer Zeichenfolge in einer Zeichenfolgeninstanz zurückgibt.
LastIndexOfAny, die einen auf null basierenden Index in der aktuellen Zeichenfolgeninstanz des letzten Vorkommens eines beliebigen Zeichens in einem Zeichenarray zurückgibt.
Im folgenden Beispiel wird die IndexOf-Methode verwendet, um die Punkte in einer Zeichenfolge zu finden. Anschließend wird die Substring-Methode verwendet, um vollständige Sätze zurückzugeben.
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.