Способ иметь String.Replace только ударить “целые слова”

Мне нужен способ:

"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 # – мой обычный язык, поэтому ответы в любом случае прекрасны.

Регулярное выражение – самый простой способ:

 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 используйте RegexOptions.IgnoreCase :

 Regex.Replace(input, pattern, replace, RegexOptions.IgnoreCase); 

Я создал функцию (см. Запись в блоге здесь ), которая обертывает выражение регулярного выражения, предложенное Ахмадом Магедом

 ///  /// Uses regex '\b' as suggested in https://stackoverflow.com/questions/6143642/way-to-have-string-replace-only-hit-whole-words ///  ///  ///  ///  ///  ///  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 = "[email protected]" 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.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(); 
  • Извлечение числа из строки в Python
  • Объявления загружаются, но не отображаются?
  • Java: разделение запятой строки, но игнорирование запятых в кавычках
  • Java-способ проверить, является ли строка палиндром
  • Получить строку между двумя строками в строке
  • Извлечь цифры из строки в Java
  • Правильный способ разбить std :: string на вектор
  • Преобразование строкового представления списка в список
  • Подсчитайте количество строк, появляющихся в строке
  • Использование getline () в C ++
  • Почему println (массив) имеет странный выход? ("
  • Давайте будем гением компьютера.