2014-11-14 1 views
0

Я ищу решение для этого случая:Как реализовать «Найти, заменить, Далее» в строке на C#?

У меня есть метод внутри DLL, который получает строку, содержащую некоторые слова как «заполнители/параметры», которые будут заменены результатом другого конкретного метода (внутри dll тоже)

Слишком упрощенное: это строка запроса, полученная в качестве аргумента для метода внутри DLL, где X-слово, которое соответствует конкретному случаю, будет заменено.

Мой метод получить строку, которая может быть как это:

(на EXE-приложения)

string str = "INSERT INTO mydb.mytable (id_field, description, complex_number) VALUES ('#GEN_COMPLEX_ID#','A complex solution', '#GEN_COMPLEX_ID#');" 

MyDLLClass.MyMethod(str); 

Итак, проблема: если я заменить # GEN_COMPLEX_ID # на этой строке , желая, чтобы в каждом совпадении было другое, это не произойдет, потому что замененный выполняет функцию в одиночном кадре (не шаг за шагом). Итак, я хочу помочь в реализации этого: шаг за шагом заменить любой текст (например, найти слово, заменить, а затем следующий ... заменить ... следующий ... и т. Д.)

Не могли бы вы мне помочь? Спасибо!

+2

вам нужно делать регулярные выражения, или это будет просто заменить простой заполнитель? Как «большая» эта строка? Это файл? Нужно ли его загружать в память в этом случае? Почему вы не заменяете заполнители перед конкатенацией? Что означает «Следующий» для вас? У вас есть какой-то графический интерфейс, который должен позволить пользователю проходить через строку? – Groo

+0

Спасибо за быстрый ответ. –

+0

Почему вы не заменяете заполнители один за другим внутри цикла 'for'? – Groo

ответ

1

Это работает очень хорошо для меня:

 string yourOriginalString = "ab cd ab cd ab cd"; 
     string pattern = "ab"; 
     string yourNewDescription = "123"; 
     int startingPositionOffset = 0; 
     int yourOriginalStringLength = yourOriginalString.Length; 

     MatchCollection match = Regex.Matches(yourOriginalString, pattern, RegexOptions.IgnoreCase | RegexOptions.Multiline); 

     foreach (Match m in match) 
     { 
      yourOriginalString = yourOriginalString.Substring(0, m.Index+startingPositionOffset) + yourNewDescription + yourOriginalString.Substring(m.Index + startingPositionOffset+ m.Length); 
      startingPositionOffset = yourOriginalString.Length - yourOriginalStringLength; 
     } 
+0

вот решение! Большое спасибо! –

+0

Хотя это даст правильные результаты, рекомендуется компоновать выходную строку с помощью 'StringBuilder', а не конкатенации, поскольку последняя создает новые экземпляры строк в каждой операции. Это означает, что этот алгоритм является esaentially 'O (n * m)', если * n * - длина и * m * - счетчик закладок, а также создает ненужную нагрузку GC (* m * распределения длины * n *, а затем * m * коллекции). 'Regex.Replace' также использует' StringBuilder' внутри. – Groo

0

вы должны использовать метод разделения, как этот

 string [] placeholder = {"#Placeholder#"} ; 
     string[] request = cd.Split(placeholder, StringSplitOptions.RemoveEmptyEntries); 
     StringBuilder requetBuilding = new StringBuilder(); 
     requetBuilding.Append(request[0]); 
     int index = 1; 
     requetBuilding.Append("Your place holder replacement"); 
     requetBuilding.Append(request[index]); 
     index++; //next replacement 
        // requetBuilding.Append("Your next place holder replacement"); 
        // requetBuilding.Append(request[index]); 
0

Если вы спрашиваете, как заменить каждый заполнитель с другим значением, вы можете сделать это с помощью Regex.Replace перегрузки, который принимает MatchEvaluator делегат и выполняет его для каждого матча:

// conceptually, something like this (note that it's not checking if there are 
// enough values in the replacementValues array) 

static string ReplaceMultiple(
     string input, string placeholder, IEnumerable<string> replacementValues) 
{ 
    var enumerator = replacementValues.GetEnumerator(); 
    return Regex.Replace(input, placeholder, 
     m => { enumerator.MoveNext(); return enumerator.Current; }); 
} 

Это, конечно, предполагается, что все заполнители выглядят одинаково.

0

Псевдо-код

var split = source.Split(placeholder); // create array of items without placeholders 
var result = split[0]; // copy first item 
for(int i = 1; i < result.Length; i++) 
{ 
    bool replace = ... // ask user 
    result += replace ? replacement : placeholder; // to put replacement or not to put 
    result += split[i]; // copy next item 
} 
Смежные вопросы