Как заменить часть строки позицией? - PullRequest
134 голосов
/ 16 февраля 2011

У меня есть эта строка: ABCDEFGHIJ

Мне нужно заменить из положения 4 в положение 5 строкой ZX

Это будет выглядеть так: ABCZXFGHIJ

Но не использовать с string.replace("DE","ZX") - мне нужно использовать с position

Как я могу это сделать?

Ответы [ 16 ]

178 голосов
/ 16 февраля 2011

Самый простой способ добавить и удалить диапазоны в строке - это использовать StringBuilder.

var theString = "ABCDEFGHIJ";
var aStringBuilder = new StringBuilder(theString);
aStringBuilder.Remove(3, 2);
aStringBuilder.Insert(3, "ZX");
theString = aStringBuilder.ToString();

Альтернативой является использование String.Substring, но я думаю, что код StringBuilder становится более читабельным.

154 голосов
/ 16 февраля 2011
string s = "ABCDEFGH";
s= s.Remove(3, 2).Insert(3, "ZX");
35 голосов
/ 20 марта 2014

ReplaceAt (индекс int, длина int, замена строки)

Вот метод расширения, который не использует StringBuilder или Substring.Этот метод также позволяет замещающей строке выходить за пределы длины исходной строки.

//// str - the source string
//// index- the start location to replace at (0-based)
//// length - the number of characters to be removed before inserting
//// replace - the string that is replacing characters
public static string ReplaceAt(this string str, int index, int length, string replace)
{
    return str.Remove(index, Math.Min(length, str.Length - index))
            .Insert(index, replace);
}

При использовании этой функции, если вы хотите, чтобы вся замещающая строка заменяла столько символов, сколько возможно, установите для длины значениедлина строки замены:

"0123456789".ReplaceAt(7, 5, "Hello") = "0123456Hello"

В противном случае вы можете указать количество символов, которое будет удалено:

"0123456789".ReplaceAt(2, 2, "Hello") = "01Hello456789"

Если указать длину, равную 0, то этофункция действует так же, как и функция вставки:

"0123456789".ReplaceAt(4, 0, "Hello") = "0123Hello456789"

Я полагаю, это более эффективно, поскольку класс StringBuilder не нужно инициализировать и поскольку он использует более простые операции.Пожалуйста, поправьте меня, если я ошибаюсь.:)

9 голосов
/ 16 февраля 2011

Используйте String.Substring() (подробности здесь ), чтобы вырезать левую часть, затем замену, затем правую часть. Играйте с индексами, пока не поймете это правильно:)

Что-то вроде:

string replacement=original.Substring(0,start)+
    rep+original.Substring(start+rep.Length);
7 голосов
/ 08 октября 2013

как метод расширения.

public static class StringBuilderExtension
{
    public static string SubsituteString(this string OriginalStr, int index, int length, string SubsituteStr)
    {
        return new StringBuilder(OriginalStr).Remove(index, length).Insert(index, SubsituteStr).ToString();
    }
}
5 голосов
/ 16 февраля 2011
        string s = "ABCDEFG";
        string t = "st";
        s = s.Remove(4, t.Length);
        s = s.Insert(4, t);
3 голосов
/ 29 июня 2017

Все остальные ответы не работают, если строка содержит символ Unicode (например, Emojis) , потому что символ Unicode весит больше байтов, чем символ.

Пример : смайлики '?', преобразованные в байты, будут весить эквивалент 2 символов. Таким образом, если символ unicode находится в начале вашей строки, параметр offset будет смещен).

С помощью этой темы я расширяю класс StringInfo до Replace на позицию, сохраняя алгоритм Ника Миллера, чтобы избежать этого:

public static class StringInfoUtils
{
    public static string ReplaceByPosition(this string str, string replaceBy, int offset, int count)
    {
        return new StringInfo(str).ReplaceByPosition(replaceBy, offset, count).String;
    }

    public static StringInfo ReplaceByPosition(this StringInfo str, string replaceBy, int offset, int count)
    {
        return str.RemoveByTextElements(offset, count).InsertByTextElements(offset, replaceBy);
    }

    public static StringInfo RemoveByTextElements(this StringInfo str, int offset, int count)
    {
        return new StringInfo(string.Concat(
            str.SubstringByTextElements(0, offset),
            offset + count < str.LengthInTextElements
                ? str.SubstringByTextElements(offset + count, str.LengthInTextElements - count - offset)
                : ""
            ));
    }
    public static StringInfo InsertByTextElements(this StringInfo str, int offset, string insertStr)
    {
        if (string.IsNullOrEmpty(str?.String))
            return new StringInfo(insertStr);
        return new StringInfo(string.Concat(
            str.SubstringByTextElements(0, offset),
            insertStr,
            str.LengthInTextElements - offset > 0 ? str.SubstringByTextElements(offset, str.LengthInTextElements - offset) : ""
        ));
    }
}
3 голосов
/ 01 сентября 2013

Как и другие, упоминал, что функция Substring() существует по причине:

static void Main(string[] args)
{
    string input = "ABCDEFGHIJ";

    string output = input.Overwrite(3, "ZX"); // 4th position has index 3
    // ABCZXFGHIJ
}

public static string Overwrite(this string text, int position, string new_text)
{
    return text.Substring(0, position) + new_text + text.Substring(position + new_text.Length);
}

Также я рассчитал это против решения StringBuilder и получил 900 тиков против 875. Так что это немного медленнее.

3 голосов
/ 16 февраля 2011

Вы можете попробовать что-нибудь связать это:

string str = "ABCDEFGHIJ";
str = str.Substring(0, 2) + "ZX" + str.Substring(5);
2 голосов
/ 28 апреля 2016

Еще один

    public static string ReplaceAtPosition(this string self, int position, string newValue)        
    {
        return self.Remove(position, newValue.Length).Insert(position, newValue); 
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...