Я хочу взять и отредактировать строку на месте в приложении .NET. Я знаю, что StringBuilder
позволяет мне делать на месте добавления, вставки и замены, но это не позволяет легко сделать такие вещи, как это:
while (script.IndexOf("@Unique", StringComparison.InvariantCultureIgnoreCase) != -1)
{
int Location = script.IndexOf("@Unique", StringComparison.InvariantCultureIgnoreCase);
script = script.Remove(Location, 7);
script = script.Insert(Location, Guid.NewGuid().ToString());
}
Как нет IndexOf
в StringBuilder
. Есть ли у кого-нибудь эффективный способ редактирования текстовой информации на месте?
Изменить # 1: Измененный образец, чтобы сделать более очевидным, что каждая "замена" должна иметь другой результат.
Если ваш код действительно является таким простым, почему бы просто не использовать один из встроенных методов Replace
, либо на string
, StringBuilder
или Regex
?
ИЗМЕНИТЬ СЛЕДУЮЩИЙ КОММЕНТАРИЙ...
Вы можете заменить каждое вхождение отдельным значением, используя одну из перегрузок Regex.Replace
, которая принимает аргумент MatchEvaluator
:
string foo = "blah blah @Unique blah @Unique blah blah @Unique blah";
// replace each occurrence of "@Unique" with a separate guid
string bar = Regex.Replace(foo, "@Unique",
new MatchEvaluator(m => Guid.NewGuid().ToString()),
RegexOptions.IgnoreCase));
Сколько изменений вы будете делать?
Если это не четыре цифры, а просто принять новые экземпляры строк, вы можете преждевременно оптимизировать...
Другое решение... Разделите на "@uniqueID", затем присоединитесь к StringBuilder, добавив ваш seperator для каждой итерации.
Как насчет StringBuilder
" Replace" метод:
StringBuilder script;
script.Replace("@Unique", GetGuidString());
Пользователь Dennis предоставил метод расширения IndexOf для StringBuilder. Таким образом, вы должны иметь возможность использовать StringBuilder таким образом.
StringBuilder создан таким образом, что вы можете легко добавить к нему, но при компромиссе, который трудно найти в нем - и тем более сложнее (т.е. медленнее) индексировать его. Если вам нужно изменить некоторые символы "на месте", лучше всего сделать это в результирующей строке.
Но с вашего вопроса трудно понять, какой правильный ответ для вас, я чувствую, что вам не нужно заменять место на месте в StringBuilder, и проблема в другом месте/вы делаете что-то еще неправильно.
но должен быть эффективным решением
public StringBuilder Replace(this StringBuilder sb, string toReplace, Func<string> getReplacement)
{
for (int i = 0; i < sb.Length; i++)
{
bool replacementFound = true;
for (int toReplaceIndex = 0; toReplaceIndex < toReplace.Length; toReplaceIndex++)
{
int sbIndex = toReplaceIndex + i;
if (sbIndex < sb.Length)
{
return sb;
}
if (sb[sbIndex] != toReplace[toReplaceIndex])
{
replacementFound = false;
break;
}
}
if (replacementFound)
{
string replacement = getReplacement();
// reuse the space of the toReplace string
for (int replacementIndex = 0; replacementIndex < toReplace.Length && replacementIndex < replacement.Length; replacementIndex++)
{
int sbIndex = replacementIndex + i;
sb[sbIndex] = replacement[i];
}
// remove toReplace string remainders
if (replacement.Length < toReplace.Length)
{
sb.Remove(i + replacement.Length, replacement.Length - toReplace.Length)
}
// insert chars not yet inserted
if (replacement.Length > toReplace.Length)
{
sb.Insert(i + toReplace.Length, replacement.ToCharArray(toReplace.Length, toReplace.Length - replacement.Length));
}
}
}
return sb;
}
случай использования
var sb = new StringBuilder(script);
script = sb.Replace("@Unique", () => Guid.NewGuid().ToString()).ToString();
Можете ли вы использовать разделение строк, чтобы сделать это эффективно?
Что-то вроде:
var sections = "a-@Unique-b-@Unique-c".Split(new string[] { "@Unique" }, StringSplitOptions.None);
int i;
StringBuilder builder = new StringBuilder();
for(i = 0; i < sections.Length - 1; i++)
{
builder.Append(sections[i]);
builder.Append(Guid.NewGuid().ToString());
}
builder.Append(sections[i]);
Console.WriteLine(builder.ToString());
Console.ReadKey(true);
Вам понадобится использовать неуправляемый блок кода Так же просто, как объявить указатель на свою строку и манипулировать ею в памяти.
Пример
unsafe
{
char* ip;
ip = &to_your_string;
}
Regex.Replace
. Взгляните на мою правку.