끈을 가지는 방법.누른 "전체 단어"만 바꾸기
나는 이것을 가질 방법이 필요합니다.
"test, and test but not testing. But yes to test".Replace("test", "text")
반환:
"text, and text but not testing. But yes to text"
기본적으로 전체 단어를 바꾸고 싶지만 부분 일치는 아닙니다.
참고: 이(SSRS 2008 코드)에는 VB를 사용해야 하지만, C#은 제가 사용하는 일반 언어이므로 어느 쪽이든 반응이 좋습니다.
정규식은 가장 쉬운 접근 방식입니다.
string input = "test, and test but not testing. But yes to test";
string pattern = @"\btest\b";
string replace = "text";
string result = Regex.Replace(input, pattern, replace);
Console.WriteLine(result);
패턴의 중요한 부분은\b
단어 경계와 일치하는 메타 문자입니다.대소문자를 구분하지 않고 사용해야 하는 경우RegexOptions.IgnoreCase
:
Regex.Replace(input, pattern, replace, RegexOptions.IgnoreCase);
아흐마드 매지드가 제안한 정규 표현식을 감싸는 기능(여기 블로그 게시물 참조)을 만들었습니다.
/// <summary>
/// Uses regex '\b' as suggested in https://stackoverflow.com/questions/6143642/way-to-have-string-replace-only-hit-whole-words
/// </summary>
/// <param name="original"></param>
/// <param name="wordToFind"></param>
/// <param name="replacement"></param>
/// <param name="regexOptions"></param>
/// <returns></returns>
static public string ReplaceWholeWord(this string original, string wordToFind, string replacement, RegexOptions regexOptions = RegexOptions.None)
{
string pattern = String.Format(@"\b{0}\b", wordToFind);
string ret=Regex.Replace(original, pattern, replacement, regexOptions);
return ret;
}
Sga가 언급한 것처럼 정규식 솔루션은 완벽하지 않습니다.그리고 공연에 친화적이지도 않은 것 같아요.
여기 제 기여가 있습니다.
public static class StringExtendsionsMethods
{
public static String ReplaceWholeWord ( this String s, String word, String bywhat )
{
char firstLetter = word[0];
StringBuilder sb = new StringBuilder();
bool previousWasLetterOrDigit = false;
int i = 0;
while ( i < s.Length - word.Length + 1 )
{
bool wordFound = false;
char c = s[i];
if ( c == firstLetter )
if ( ! previousWasLetterOrDigit )
if ( s.Substring ( i, word.Length ).Equals ( word ) )
{
wordFound = true;
bool wholeWordFound = true;
if ( s.Length > i + word.Length )
{
if ( Char.IsLetterOrDigit ( s[i+word.Length] ) )
wholeWordFound = false;
}
if ( wholeWordFound )
sb.Append ( bywhat );
else
sb.Append ( word );
i += word.Length;
}
if ( ! wordFound )
{
previousWasLetterOrDigit = Char.IsLetterOrDigit ( c );
sb.Append ( c );
i++;
}
}
if ( s.Length - i > 0 )
sb.Append ( s.Substring ( i ) );
return sb.ToString ();
}
}
테스트 사례 포함:
String a = "alpha is alpha";
Console.WriteLine ( a.ReplaceWholeWord ( "alpha", "alphonse" ) );
Console.WriteLine ( a.ReplaceWholeWord ( "alpha", "alf" ) );
a = "alphaisomega";
Console.WriteLine ( a.ReplaceWholeWord ( "alpha", "xxx" ) );
a = "aalpha is alphaa";
Console.WriteLine ( a.ReplaceWholeWord ( "alpha", "xxx" ) );
a = "alpha1/alpha2/alpha3";
Console.WriteLine ( a.ReplaceWholeWord ( "alpha", "xxx" ) );
a = "alpha/alpha/alpha";
Console.WriteLine ( a.ReplaceWholeWord ( "alpha", "alphonse" ) );
이 특정 정규식 패턴에 대한 참고 사항을 추가하고 싶습니다(승인된 답변과 바꾸기 모두에 사용됨).전체 워드 함수).대체하려는 내용이 단어가 아니면 작동하지 않습니다.
여기 테스트 사례:
using System;
using System.Text.RegularExpressions;
public class Test
{
public static void Main()
{
string input = "doin' some replacement";
string pattern = @"\bdoin'\b";
string replace = "doing";
string result = Regex.Replace(input, pattern, replace);
Console.WriteLine(result);
}
}
(코드 시도 준비 완료: http://ideone.com/2Nt0A)
특히 일괄 번역을 하는 경우(제가 일부 i18n 작업에서 했던 것처럼) 이 점을 고려해야 합니다.
단어를 구성하는 문자(예: "_" 및 "@")를 정의하려면
제 (vb.net ) 기능을 사용할 수 있습니다.
Function Replace_Whole_Word(Input As String, Find As String, Replace As String)
Dim Word_Chars As String = "ABCDEFGHIJKLMNOPQRSTUVWYXZabcdefghijklmnopqrstuvwyxz0123456789_@"
Dim Word_Index As Integer = 0
Do Until False
Word_Index = Input.IndexOf(Find, Word_Index)
If Word_Index < 0 Then Exit Do
If Word_Index = 0 OrElse Word_Chars.Contains(Input(Word_Index - 1)) = False Then
If Word_Index + Len(Find) = Input.Length OrElse Word_Chars.Contains(Input(Word_Index + Len(Find))) = False Then
Input = Mid(Input, 1, Word_Index) & Replace & Mid(Input, Word_Index + Len(Find) + 1)
End If
End If
Word_Index = Word_Index + 1
Loop
Return Input
End Function
시험
Replace_Whole_Word("We need to replace words tonight. Not to_day and not too well to", "to", "xxx")
결과
"We need xxx replace words tonight. Not to_day and not too well xxx"
나는 레젝스가 느려서 좋아하지 않습니다.제 기능이 더 빠릅니다.
public static string ReplaceWholeWord(this string text, string word, string bywhat)
{
static bool IsWordChar(char c) => char.IsLetterOrDigit(c) || c == '_';
StringBuilder sb = null;
int p = 0, j = 0;
while (j < text.Length && (j = text.IndexOf(word, j, StringComparison.Ordinal)) >= 0)
if ((j == 0 || !IsWordChar(text[j - 1])) &&
(j + word.Length == text.Length || !IsWordChar(text[j + word.Length])))
{
sb ??= new StringBuilder();
sb.Append(text, p, j - p);
sb.Append(bywhat);
j += word.Length;
p = j;
}
else j++;
if (sb == null) return text;
sb.Append(text, p, text.Length - p);
return sb.ToString();
}
이 방법은 또한 관심이 있는 경우 케이스를 무시합니다.
public static string Replace(this string s, string word, string by, StringComparison stringComparison, bool WholeWord)
{
s = s + " ";
int wordSt;
StringBuilder sb = new StringBuilder();
while (s.IndexOf(word, stringComparison) > -1)
{
wordSt = s.IndexOf(word, stringComparison);
if (!WholeWord || ((wordSt == 0 || !Char.IsLetterOrDigit(char.Parse(s.Substring(wordSt - 1, 1)))) && !Char.IsLetterOrDigit(char.Parse(s.Substring(wordSt + word.Length, 1)))))
{
sb.Append(s.Substring(0, wordSt) + by);
}
else
{
sb.Append(s.Substring(0, wordSt + word.Length));
}
s = s.Substring(wordSt + word.Length);
}
sb.Append(s);
return sb.ToString().Substring(0, sb.Length - 1);
}
문자열.replace를 사용할 수 있습니다.
string input = "test, and test but not testing. But yes to test";
string result2 = input.Replace("test", "text");
Console.WriteLine(input);
Console.WriteLine(result2);
Console.ReadLine();
언급URL : https://stackoverflow.com/questions/6143642/way-to-have-string-replace-only-hit-whole-words
'source' 카테고리의 다른 글
동적 SQL 문에서 테이블 변수를 사용하는 방법은 무엇입니까? (0) | 2023.07.16 |
---|---|
ggplot2에서 매핑이 안정적인 범주형 변수에 색상을 할당하는 방법은 무엇입니까? (0) | 2023.07.16 |
파이썬에서 두 사전의 차이를 얻는 방법은 무엇입니까? (0) | 2023.07.16 |
디버깅을 위해 제너레이터 개체를 목록으로 변환 (0) | 2023.07.16 |
C++ 단일 줄 주석 뒤에 다중 줄 주석의 \변환이 나옵니다. (0) | 2023.07.16 |