Sztringműveletek: Mintaegyezés, teljesítmény és span-alapú keresés

Ez a cikk három sztringműveletet mutat be: a reguláris kifejezés mintájának egyeztetése a kiosztásmentes keresésselSystem.Text.RegularExpressions.RegexReadOnlySpan<T>, és egy StringComparison érték kiválasztása a helyes, gyors összehasonlításhoz.

Adott szöveg megkeresése reguláris kifejezések használatával

Az System.Text.RegularExpressions.Regex osztály a rögzített részsztringek helyett sztringeket keres. A statikus Regex.IsMatch metódus a bemeneti sztringet, a mintát és az opcionális RegexOptions jelzőket használja.

Az alábbi példa az egyes mondatokban keres a kis- és nagybetűket érzéketlennek. A minta the(ir)?\s opcionálisan egyezik the , majd iregy szóköz karakter:

Pattern Meaning
the a literális szöveg egyeztetése the
(ir)? 0 vagy 1 előfordulása ir
\s szóköz karakter egyeztetése
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();
    }
}

Sztringek ellenőrzése mintával

Annak ellenőrzéséhez, hogy egy teljes bemenet egyezik-e egy alakzattal, rögzítse a mintát a következővel ^ : és $. Az alábbi példa ellenőrzi, hogy minden sztring amerikai stílusú telefonszám-e: három számjegy, három számjegy, négy számjegy, kötőjelekkel elválasztva:

Pattern Meaning
^ a sztring elejének egyeztetése
\d{3} pontosan három számjegy karakterének egyezése
- konstans - karakter egyeztetése
\d{4} pontosan négy számjegy karakterének egyezése
$ a sztring végének egyeztetése
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");
}

A teljes mintaszintaxisért tekintse meg a Reguláris kifejezésnyelvet – rövid útmutatót.

Válasszon a metódusok és a reguláris kifejezések közül string

string metódusok és Regex az átfedésben lévő problémák megoldása. Ha a keresett szöveg literális érték, ismert előtag vagy utótag, vagy rögzített elválasztó karakter, akkor a metódusokat előnyben részesítse string . Egyszerűbben olvashatók és gyorsabban olvashatók, mert nem fizetik meg a minta összeállításának és végrehajtásának költségeit. Regex Keresse meg, ha a keresési cél egy alakzat, például váltakozások, választható csoportok, ismétlődő karakterosztályok vagy rögzített ellenőrzés. Hüvelykujjszabályként, ha a keresést egy vagy két string.Contains / / StartsWithIndexOf hívásként is meg tudja írni, tegye meg.

Keresés a következő használatával: ReadOnlySpan<char>

Ha nagy bemeneteket elemez, vagy egy gyakori elérésű útvonalon futtat keresést, a hívásonkénti string.Substring kiosztások dominálhatnak.string.Split ReadOnlySpan<char> másolás nélkül tekinthet meg egy meglévő sztringet (tömböt vagy verempuffert), és MemoryExtensions a gyakori string metódusok span-alapú megfelelőit biztosítja, például 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

A span-alapú keresés elkerüli a foglalásokat, mert a szeletek (input[start..], rest[..end]) egyszerűen ablakok az eredeti karakterek felett. Ugyanez a megközelítés a kulcs-érték listák, fejlécek és más elhatárolt szövegek elemzésére skálázható anélkül, hogy valaha is hívna Substring.

Teljesítménnyel kapcsolatos szempontok a következőhöz: StringComparison

A legtöbb string példány metódusa túlterheléssel rendelkezik, amely elfogad egy StringComparison értéket. Olyan metódusok, mint String.Equals(String) az alapértelmezett a sorszám, de String.Compare(String, String)String.IndexOf(String) az alapértelmezett az aktuális kultúra. Ez a különbség kétféleképpen számít:

  • Sebesség. Az ordinális összehasonlítás egy byte-for-byte teszt, amely szoros, vektorizált hurkokban fut. A kultúratudatos összehasonlítás áttekint egy rendezési táblázatot, bemutatja a karakterek kombinálását, és területi szabályokat alkalmaz. Ugyanahhoz a bemenethez nagyságrenddel lassabb lehet.
  • Helyesség. A kultúratudatos összehasonlítás olyan karaktereket is összedobhat, amelyeket nem vár (török i/I, német ß és ssligatúrák). Ez a viselkedés megfelelő a felhasználó által látott nevek rendezéséhez, de helytelen az azonosítók, elérési utak vagy protokoll jogkivonatok elemzéséhez.

Gép által definiált szöveg, például fájlnevek, URL-címek, HTTP-fejlécek, azonosítók és konfigurációs kulcsok esetén adja át StringComparison.Ordinal vagy StringComparison.OrdinalIgnoreCase explicit módon. A felhasználók számára megjelenített természetes nyelvű szövegek kultúratudatos értékeinek lefoglalása. Átfogó útmutatásért lásd a Best eljárásokat a sztringek .NET összehasonlítása céljából.

Lásd még