2016-08-09 2 views
0

Я пытаюсь создать функцию, заменяющую только целые слова, например:заменить только целые слова C#

предложение: «#testing является #test», если я использую Replace («# тест», " #cool "), я буду иметь„#cooling если #cool“, но я хотел бы иметь„#testing является #cool“

Я искал и каждый ответ был найден:

string pattern = @"\b"+previousText+"\b"; 
string myText = Regex.Replace(input, pattern, newText, RegexOptions.IgnoreCase); 

Однако это решение не работает, если мой предыдущий текст (тот, который я хотел бы заменить) содержит «#».

Как мой предыдущий текст, так и мой новый текст могут начинаться с символа «#».

Какое решение для этого?

EDIT: Благодаря Legends регулярное выражение теперь работает, если слово сопровождается пробелом, но терпит неудачу, если искомое слово находится рядом с запятой:

string input = "#test, #test"; 
      string patternTest = @"#test"; 
      string newTextTest = "#cool"; 
      string result = Regex.Replace(input, @"(?:(?<=^|\s)(?=\S|$)|(?<=^|\S)(?=\s|$))" + patternTest + @"(?:(?<=^|\s)(?=\S|$)|(?<=^|\S)(?=\s|$))", newTextTest, RegexOptions.IgnoreCase); 

это возвращает: «#test, #cool» вместо «#cool, #cool»

+0

Вы должны использовать Regex для этого –

+0

, похоже, работает со словом границы только после хеш-тега '@" # test \ b "' или '@" # \ btest \ b "' – Slai

ответ

2

Следующие Regex заменят только одноместные целые слова!

var input = "#testing is #test"; 
var pattern = @"#test"; 
string myText = 
Regex.Replace(input, @"(?:(?<=^|\s)(?=\S|$)|(?<=^|\S)(?=\s|$))" + pattern + @"(?:(?<=^|\s)(?=\S|$)|(?<=^|\S)(?=\s|$))","#cool", RegexOptions.IgnoreCase); 


Результат:

#testing является #cool


Это должно работать с запятыми и двоеточия непосредственно до и после слова:

var input = "#test, is ;#test"; 
var searchString = @"#test"; 
var replaceWith = "#cool"; 
var pattern = @"(?:(?<=^|(\s|,|;))(?=\S|$)|(?<=^|\S)(?=\s|$))" 
       + searchString + 
       @"(?:(?<=^|(\s))(?=\S|$)|(?<=^|\S)(?=(\s|,|;)|$))"; 

string myText = Regex.Replace(input, pattern, replaceWith, RegexOptions.IgnoreCase); 

Результат:

#cool, является, #cool


Это одна будет работать со всеми следующими символами до и после слова

Например:

  1. , слово или слово,
  2. слово; или, слово
  3. .word или ....

,; ,- '

var input = "#test's is #test."; 
var searchString = @"#test"; 
var replaceWith = "#cool"; 
var pattern = @"(?:(?<=^|(\s|,|;|-|:|\.|'))(?=\S|$)|(?<=^|\S)(?=\s|$))" 
       + searchString + 
       @"(?:(?<=^|(\s))(?=\S|$)|(?<=^|\S)(?=(\s|,|;|-|:|\.|')|$))"; 
string myText = Regex.Replace(input,pattern ,replaceWith, RegexOptions.IgnoreCase); 

Результат:

# Куля является #cool.

+1

Кажется идеальным, спасибо! – user2088807

+0

Не работает «апостроф». Ошибка при переносе. – Aron

+1

Кажется, что сбой, если за словом следует запятая, см. Мое редактирование для примера. – user2088807

1

Если вы не хотите использовать регулярное выражение для какой-то причине, вы можете сделать это без него, а также:

var split_options = new [] {' ', '.', ',' ...}; // Use whatever you might have here. 
var input = "#testing is #test".Split(split_options 
             , StringSplitOptions.RemoveEmptyEntries); 
var word_to_replace = "#test"; 
var new_text = "#cool"; 
for (int i = 0; i < input.Length; i++) 
{ 
    if (input[i].Equals(word_to_replace)) 
    input[i] = new_text; 
} 
var output = string.Join(" ",input); 

// your output is "#testing is #cool" 

Вы можете поместить это в метод или метод расширения, и это будет сделайте вас чистым кодом.

+0

Я не пробовал это решение раньше, я думал, что было бы более уродливо делать, хороший пример. Я сравню производительность с Regex – user2088807

+0

То же самое, но другое, просто давая вам варианты :). если честно, я считаю, что регулярное выражение должно быть медленнее, но для всех практических применений это не имеет значения. Я отредактирую его, чтобы отправить комментарии на другой ответ. – Noctis

Смежные вопросы