Как иметь строку.Заменить только хит " целые слова"
мне нужно вот что:
"test, and test but not testing. But yes to test".Replace("test", "text")
вернуть этого:
"text, and text but not testing. But yes to text"
в основном я хочу заменить целые слова, но не частичные совпадения.
примечание: Я собираюсь использовать VB для этого (код SSRS 2008), но C# - мой обычный язык, поэтому ответы в любом случае прекрасны.
6 ответов:
в regex, это самый простой подход:
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);
Я создал функцию (см. сообщение в блоге здесь), который обертывает выражение regex, предложенное Ахмад Mageed
/// <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" ) );
Я просто хочу добавить заметку об этом конкретном шаблоне регулярных выражений (используется как в принятом ответе, так и в ReplaceWholeWord). Это не работает, если то, что вы пытаетесь заменить, не является слово.
вот тестовый пример:
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"
вы можете использовать строку.заменить
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();
Comments