2014-01-27 2 views
1

мне нужно заменить несколько подстрок в строкеЗаменить несколько подстрок в строке

Скажут:

  • заменить все А в исходной строке на B
  • заменить все B в исходной строке на D

так, например, "AB дает BD"

"наивный" соответствую ach не работает должным образом:

string S="AB"; 
S=S.Replace("A","B"); 
S=S.Replace("B","D"); 

как он даст DD вместо BD. (сначала A заменяется на B, но затем без необходимости изменяется на D)

Как бороться с такими случаями? Имеет ли смысл подстроки любого размера делать такие отдельные замены?

EDIT: Я привел пример не реальной жизни, где на самом деле он работал бы в обратном порядке (сначала от B до D, затем от A до B). Но, как другие заметили, меня интересуют более общие решения: для любого списка замещений символов и для любого списка замещений слов

С символами, я полагаю, теперь хороший подход состоит только в том, чтобы пройти через все символы в строке и построить новую строку, заменяя при необходимости.

Для слов, я полагаю, это может быть сложнее, а что, если одно замеченное слово является частью другого слова?

Например

string S="man superman woman superwoman" 

и я хочу заменить «человека» на «мальчик» и «женщина» на «девочка» только как отдельные слова

+0

просто сделать это в обратном направлении, B к D, а затем А до Б – NoviceProgrammer

+0

У вас есть только отдельные символы, чтобы заменить или что бы ваш реальный случай? –

+0

Loop лучше всего, но вы можете заменить * в нижнем регистре *, затем toUpper(), когда вы сделали –

ответ

3

Один простой способ это просто цикл по строке и затем использовать инструкцию if-else или switch для проверки символов и соответственно их изменения.

Таким образом, символы меняются только один раз.

var testString = "Hello World"; 
var newString = new StringBuilder(); 

foreach (char c in testString) 
{ 
    switch (c) 
    { 
     case 'e': 
      newString.Append('l'); 
      break; 
     case 'l': 
      newString.Append('e'); 
      break; 
     default: 
      newString.Append(c); 
      break; 
    } 
} 

// testString will be "Hleeo Wored" 
testString = newString.ToString(); 
+0

StringBuilder, см. Обновленный ответ :) – Blam

4

Предполагая, что циклов нет, вам нужно сделать это наоборот. Значение:

string S="AB"; 
S=S.Replace("B","D"); 
S=S.Replace("A","B"); 

Таким образом, B переходит в D, то переключается в B и у вас нет нежелательных изменений.

Как отметил Никлас Б., в случае общих подстрок есть другой способ, который, вероятно, следует принять.

Я бы перебирал строку, сохраняя индексы, где появляется какая-либо подстрока. Сделав это, я пойду вперед и выполняю фактическое переключение. Таким образом, вы не можете «перевернуть» сделанные вами изменения.

+0

Sooo, что вы делаете с общими строками вместо одиночных символов? Этот случай тривиален, но общий случай не –

+0

@NiklasB. Если есть необходимость в общих подстроках, я бы искал появления всех подстрок, которые нужно изменить, и сохранить индексы, и как только я закончу, я буду продолжать и выполнять переключатели. –

+0

Это хороший способ продолжить это, вы должны написать это в свой ответ, так как OP явно задал этот вопрос. –

2

Вы можете сначала заменить «A» на токен, который, конечно же, не будет происходить в исходной строке.

Например:

S=S.Replace("A","#"); 
S=S.Replace("B","D"); 
S=S.Replace("#","B"); 
+0

Теперь вы просто заменили все вхождения 'A' и' # 'на' B' вместо просто 'A'. – Harrison

+0

@Harrison: «токен, который, конечно же, не встречается в исходной строке» –

-1

Просто изменить порядок строк кода:

string S="AB"; 
S=S.Replace("B","D"); 
S=S.Replace("A","B"); 
+0

Он дает простой пример: это может быть более сложным, и ваш ответ может не работать с более сложной строкой. – Guigui

0

Используйте Regex.Replace

Как коде ниже, вы можете сопоставить строки, которые вы хотите заменить их замену. Это более чистое, а для некоторых - более читаемого

IDictionary<string,string> map = new Dictionary<string,string>() 
     { 
      {"A","B"}, 
      {"B","D"}, 
     }; 
var regex = new Regex(String.Join("|",map.Keys)); 
var newStr = regex.Replace(str, m => map[m.Value]); 
Смежные вопросы