Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym artykule opisano trzy operacje ciągów: wzorzec wyrażeń regularnych zgodny z System.Text.RegularExpressions.Regexwyszukiwaniem bez ReadOnlySpan<T>alokacji w usłudze i wybranie StringComparison wartości dla poprawnych, szybkich porównań.
Znajdowanie określonego tekstu przy użyciu wyrażeń regularnych
Klasa System.Text.RegularExpressions.Regex wyszukuje ciągi dla wzorców, a nie stałych podciągów. Metoda statyczna Regex.IsMatch przyjmuje ciąg wejściowy, wzorzec i opcjonalne RegexOptions flagi.
Poniższy przykład wyszukuje każde zdanie dla wyrazu lub , bez uwzględniania wielkości liter. Wzorzec the(ir)?\s jest opcjonalnie zgodny the z irznakiem , a następnie znakiem odstępu:
| Wzór | Meaning |
|---|---|
the |
dopasuj tekst literału the |
(ir)? |
dopasowanie 0 lub 1 wystąpienia ir |
\s |
dopasuj znak odstępu |
string[] sentences =
[
"Put the water over there.",
"They're quite thirsty.",
"Their water bottles broke."
];
string pattern = @"the(ir)?\s";
foreach (string s in sentences)
{
Console.Write($"{s,28}");
if (Regex.IsMatch(s, pattern, RegexOptions.IgnoreCase))
{
Console.WriteLine($" (match for '{pattern}' found)");
}
else
{
Console.WriteLine();
}
}
Weryfikowanie ciągów względem wzorca
Aby sprawdzić, czy całe dane wejściowe pasują do kształtu, zakotwiczyć wzorzec za pomocą elementu ^ i $. Poniższy przykład sprawdza, czy każdy ciąg jest numerem telefonu w stylu USA: trzy cyfry, trzy cyfry, cztery cyfry, oddzielone kreskami:
| Wzór | Meaning |
|---|---|
^ |
dopasuj początek ciągu |
\d{3} |
dopasuj dokładnie trzy cyfry |
- |
dopasuj znak literału - |
\d{4} |
dopasuj dokładnie cztery cyfry |
$ |
dopasuj do końca ciągu |
string[] numbers =
[
"123-555-0190",
"444-234-22450",
"690-555-0178",
"146-893-232",
"146-555-0122",
"4007-555-0111",
"407-555-0111",
"407-2-5555",
"407-555-8974",
"407-2ab-5555",
"690-555-8148",
"146-893-232-"
];
string pattern = """^\d{3}-\d{3}-\d{4}$""";
foreach (string s in numbers)
{
Console.Write($"{s,14}");
Console.WriteLine(Regex.IsMatch(s, pattern) ? " - valid" : " - invalid");
}
Aby uzyskać pełną składnię wzorca, zobacz Język wyrażeń regularnych — krótki przewodnik.
Wybieranie metod string i wyrażeń regularnych
string metody i Regex rozwiązywanie nakładających się problemów. Preferuj string metody, gdy wyszukiwany tekst jest wartością literału, znanym prefiksem lub sufiksem albo stałym ogranicznikiem. Są one prostsze do odczytania i szybszego, ponieważ nie płacą kosztów kompilowania i wykonywania wzorca.
Regex Osiągaj, gdy element docelowy wyszukiwania jest kształtem, takim jak zmiany, opcjonalne grupy, powtarzające się klasy znaków lub walidacja zakotwiczona. Jeśli możesz napisać wyszukiwanie jako jedno lub dwa string.Contains / / StartsWithIndexOf wywołania, zrób to.
Wyszukiwanie przy użyciu ReadOnlySpan<char>
Podczas analizowania dużych danych wejściowych lub uruchamiania wyszukiwania na ścieżce gorącej string.Substring alokacje poszczególnych wywołań i string.Split mogą dominować.
ReadOnlySpan<char> Zapewnia widok na istniejący ciąg (lub tablicę lub bufor stosu) bez kopiowania i MemoryExtensions zapewnia odpowiedniki opartych na zakresie typowych string metod, w tym IndexOf:
ReadOnlySpan<char> input = "key1=alpha;key2=beta;key3=gamma".AsSpan();
ReadOnlySpan<char> needle = "key2=".AsSpan();
int start = input.IndexOf(needle);
if (start >= 0)
{
ReadOnlySpan<char> rest = input[(start + needle.Length)..];
int end = rest.IndexOf(';');
ReadOnlySpan<char> value = end >= 0 ? rest[..end] : rest;
Console.WriteLine($"key2 = {value}");
}
// => key2 = beta
Wyszukiwanie oparte na zakresie pozwala uniknąć alokacji, ponieważ wycinki (input[start..], rest[..end]) są po prostu oknami nad oryginalnymi znakami. To samo podejście skaluje do analizowania list klucz-wartość, nagłówków i innego tekstu rozdzielanego bez wywoływania metody Substring.
Zagadnienia dotyczące wydajności StringComparison
Większość string metod wystąpienia ma przeciążenia, które akceptują StringComparison wartość. Metody, takie jak String.Equals(String) domyślne, porządkowe, ale String.Compare(String, String) domyślne dla String.IndexOf(String)bieżącej kultury. Ta różnica ma znaczenie na dwa sposoby:
- Prędkość. Porównanie porządkowe to test bajtowy dla bajtów uruchamiany w ciasnych, wektoryzowanych pętlach. Porównanie obsługujące kulturę sprawdza tabelę sortowania, przeprowadza łączenie znaków i stosuje reguły specyficzne dla ustawień regionalnych. W przypadku tych samych danych wejściowych może to być kolejność wielkości wolniej.
- Poprawność Porównanie z uwzględnieniem kultury może składać znaki, których nie oczekujesz (turecki
i/I, niemieckißdoss, ligatur). To zachowanie jest właściwe w przypadku sortowania nazw, które użytkownik widzi, ale nie tak w przypadku analizowania identyfikatorów, ścieżek lub tokenów protokołu.
W przypadku tekstu zdefiniowanego przez maszynę, takiego jak nazwy plików, adresy URL, nagłówki HTTP, identyfikatory i klucze konfiguracji, przekaż StringComparison.Ordinal lub StringComparison.OrdinalIgnoreCase jawnie. Zarezerwuj wartości obsługujące kulturę dla tekstu w języku naturalnym wyświetlanego użytkownikom. Aby uzyskać kompleksowe wskazówki, zobacz Najest rozwiązania dotyczące porównywania ciągów w .NET.