이 문서에서는 정규식 패턴 일치 System.Text.RegularExpressions.Regex, 할당 없는 검색 ReadOnlySpan<T>및 정확하고 빠른 비교를 StringComparison 위한 값 선택이라는 세 가지 문자열 작업을 다룹니다.
정규식을 사용하여 특정 텍스트 찾기
클래스는 System.Text.RegularExpressions.Regex 문자열에서 고정 부분 문자열이 아닌 패턴을 검색합니다. 정적 Regex.IsMatch 메서드는 입력 문자열, 패턴 및 선택적 RegexOptions 플래그를 사용합니다.
다음 예제에서는 각 문장에서 대/소문자를 구분하지 않는 단어를 검색합니다. 패턴 the(ir)?\s 은 필요에 따라 일치한 ir다음 공백 문자와 일치 the 합니다.
| 패턴 | Meaning |
|---|---|
the |
리터럴 텍스트와 일치 the |
(ir)? |
일치 0 또는 1 발생 ir |
\s |
공백 문자 일치 |
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();
}
}
패턴에 대한 문자열 유효성 검사
전체 입력이 셰이프와 일치하는지 확인하려면 패턴을 와 함께 ^ 고정합니다 $. 다음 예제에서는 각 문자열이 미국식 전화 번호인지 확인합니다. 세 자리, 세 자리, 네 자리, 대시로 구분됩니다.
| 패턴 | Meaning |
|---|---|
^ |
문자열의 시작 부분과 일치 |
\d{3} |
정확히 세 자리 문자와 일치 |
- |
리터럴 - 문자 일치 |
\d{4} |
정확히 4자리 문자와 일치 |
$ |
문자열의 끝과 일치 |
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");
}
전체 패턴 구문은 정규식 언어- 빠른 참조를 참조하세요.
메서드와 정규식 중에서 string 선택
string 메서드를 사용하여 Regex 겹치는 문제를 해결합니다. 검색하는 텍스트가 리터럴 값, 알려진 접두사 또는 접미사 또는 고정 구분 기호인 경우 메서드를 사용하는 것이 좋습니다 string . 패턴을 컴파일하고 실행하는 데 드는 비용을 지불하지 않으므로 읽기가 더 간단하고 더 빠릅니다.
Regex 검색 대상이 교대, 선택적 그룹, 반복되는 문자 클래스 또는 고정된 유효성 검사와 같은 셰이프인 경우에 도달합니다. 엄지 손가락의 규칙으로, 하나 또는 두 개의 string.Contains / / StartsWithIndexOf 호출로 검색을 작성할 수 있는 경우 이렇게 합니다.
다음을 사용하여 검색 ReadOnlySpan<char>
큰 입력을 구문 분석하거나 핫 경로에서 검색을 실행하면 호출당 할당이 string.Substring 지배할 string.Split 수 있습니다.
ReadOnlySpan<char>에서는 복사하지 않고 기존 문자열(또는 배열 또는 스택 버퍼)에 대한 보기를 제공하고 다음 MemoryExtensions 을 비롯한 IndexOf일반적인 string 메서드의 범위 기반 해당 항목을 제공합니다.
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
범위 기반 검색은 조각(input[start..], rest[..end])이 단순히 원래 문자의 창이므로 할당을 방지합니다. 동일한 접근 방식은 키-값 목록, 헤더 및 기타 구분된 텍스트를 호출 Substring하지 않고 구문 분석하도록 확장됩니다.
StringComparison에 대한 성능 고려 사항
대부분의 string 인스턴스 메서드에는 값을 허용하는 오버로드가 있습니다 StringComparison . 기본값은 서수로String.Compare(String, String), 기본값은 현재 문화권과 String.IndexOf(String) 같은 String.Equals(String) 메서드입니다. 이 차이는 다음 두 가지 방법으로 중요합니다.
- 속도. 서수 비교는 타이트하고 벡터화된 루프에서 실행되는 바이트 대 바이트 테스트입니다. 문화권 인식 비교는 정렬 테이블을 참조하고, 문자 결합을 안내하고, 로캘별 규칙을 적용합니다. 동일한 입력의 경우 크기가 더 느려질 수 있습니다.
- 정확성. 문화권 인식 비교는 기대하지 않는 문자를 접을 수 있습니다(터키
i/I어, 독일어ß,ss합자). 이 동작은 사용자가 보는 이름을 정렬하는 데 적합하지만 식별자, 경로 또는 프로토콜 토큰을 구문 분석하는 데는 잘못되었습니다.
파일 이름, URL, HTTP 헤더, 식별자 및 구성 키와 같은 컴퓨터 정의 텍스트의 경우 전달 StringComparison.Ordinal 하거나 명시적으로 전달합니다 StringComparison.OrdinalIgnoreCase . 사용자에게 표시되는 자연어 텍스트에 대한 문화권 인식 값을 예약합니다. 포괄적인 지침은 .NET 문자열을 비교하기 위한
참고하십시오
.NET