Удаление символов из строки после выполнения определенного условия [duplicate]

В следующем примере, который я написал, показано, как

  • обрабатывать асинхронные HTTP-вызовы;
  • Подождать ответа от каждого вызова API;
  • Использовать шаблон promise ;
  • Используйте шаблон Promise.All для объединения нескольких HTTP-вызовов;

Этот рабочий пример является автономным. Он будет определять простой объект запроса, который использует объект window XMLHttpRequest для совершения вызовов. Он будет определять простую функцию, чтобы дождаться завершения кучи обещаний.

Контекст. В этом примере запрашивается конечная точка Spotify Web API для поиска объектов playlist для заданного набора строк запроса:

[
 "search?type=playlist&q=%22doom%20metal%22",
 "search?type=playlist&q=Adele"
]

Для каждого элемента новый Promise запустит блок - ExecutionBlock, проанализирует результат, заплатит новый набор обещаний на основе массива результатов, который представляет собой список объектов Spotify user и выполняет новый HTTP-вызов в ExecutionProfileBlock асинхронно.

Затем вы можете увидеть вложенную структуру Promise, которая позволяет вам генерировать множественные и полностью асинхронные вложенные HTTP-вызовы и присоединять результаты к каждому подмножеству вызовов через Promise.all.

NOTE Recent Spotify search API-интерфейсам потребуется указать токен доступа в заголовках запроса:

-H "Authorization: Bearer {your access token}" 

Итак, вы должны запустить следующий пример, вам нужно поместить маркер доступа в заголовки запроса:

var spotifyAccessToken = "YourSpotifyAccessToken";
var console = {
    log: function(s) {
        document.getElementById("console").innerHTML += s + "
" } } // Simple XMLHttpRequest // based on https://davidwalsh.name/xmlhttprequest SimpleRequest = { call: function(what, response) { var request; if (window.XMLHttpRequest) { // Mozilla, Safari, ... request = new XMLHttpRequest(); } else if (window.ActiveXObject) { // Internet Explorer try { request = new ActiveXObject('Msxml2.XMLHTTP'); } catch (e) { try { request = new ActiveXObject('Microsoft.XMLHTTP'); } catch (e) {} } } // State changes request.onreadystatechange = function() { if (request.readyState === 4) { // Done if (request.status === 200) { // Complete response(request.responseText) } else response(); } } request.open('GET', what, true); request.setRequestHeader("Authorization", "Bearer " + spotifyAccessToken); request.send(null); } } //PromiseAll var promiseAll = function(items, block, done, fail) { var self = this; var promises = [], index = 0; items.forEach(function(item) { promises.push(function(item, i) { return new Promise(function(resolve, reject) { if (block) { block.apply(this, [item, index, resolve, reject]); } }); }(item, ++index)) }); Promise.all(promises).then(function AcceptHandler(results) { if (done) done(results); }, function ErrorHandler(error) { if (fail) fail(error); }); }; //promiseAll // LP: deferred execution block var ExecutionBlock = function(item, index, resolve, reject) { var url = "https://api.spotify.com/v1/" url += item; console.log( url ) SimpleRequest.call(url, function(result) { if (result) { var profileUrls = JSON.parse(result).playlists.items.map(function(item, index) { return item.owner.href; }) resolve(profileUrls); } else { reject(new Error("call error")); } }) } arr = [ "search?type=playlist&q=%22doom%20metal%22", "search?type=playlist&q=Adele" ] promiseAll(arr, function(item, index, resolve, reject) { console.log("Making request [" + index + "]") ExecutionBlock(item, index, resolve, reject); }, function(results) { // Aggregated results console.log("All profiles received " + results.length); //console.log(JSON.stringify(results[0], null, 2)); ///// promiseall again var ExecutionProfileBlock = function(item, index, resolve, reject) { SimpleRequest.call(item, function(result) { if (result) { var obj = JSON.parse(result); resolve({ name: obj.display_name, followers: obj.followers.total, url: obj.href }); } //result }) } //ExecutionProfileBlock promiseAll(results[0], function(item, index, resolve, reject) { //console.log("Making request [" + index + "] " + item) ExecutionProfileBlock(item, index, resolve, reject); }, function(results) { // aggregated results console.log("All response received " + results.length); console.log(JSON.stringify(results, null, 2)); } , function(error) { // Error console.log(error); }) ///// }, function(error) { // Error console.log(error); });

Я подробно рассмотрел это решение здесь .

115
задан Mahmoud Farahat 31 August 2013 в 23:21
поделиться

14 ответов

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

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

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

157
ответ дан James Ko 28 August 2018 в 02:18
поделиться

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

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
ответ дан alykhalid 28 August 2018 в 02:18
поделиться

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

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

string replacement=original.Substring(0,start)+
    rep+original.Substring(start+rep.Length);
9
ответ дан Daniel Mošmondor 28 August 2018 в 02:18
поделиться
s.Remove(3, 2).Insert(3, "ZX");

-> Это не работает, если строка содержит символ Unicode, такой как Emojis.

С помощью в этом разделе я расширяю класс StringInfo на Replace by position, сохраняя Алгоритм Ник Миллер:

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) : ""
        ));
    }
}
2
ответ дан GGO 28 August 2018 в 02:18
поделиться

С помощью этого сообщения я создаю следующую функцию с дополнительной проверкой длины

public string ReplaceStringByIndex(string original, string replaceWith, int replaceIndex)
{
    if (original.Length >= (replaceIndex + replaceWith.Length))
    {
        StringBuilder rev = new StringBuilder(original);
        rev.Remove(replaceIndex, replaceWith.Length);
        rev.Insert(replaceIndex, replaceWith);
        return rev.ToString();
    }
    else
    {
        throw new Exception("Wrong lengths for the operation");
    }
}
2
ответ дан Hassan 28 August 2018 в 02:18
поделиться

Как и другие, упомянутая функция 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
ответ дан ja72 28 August 2018 в 02:18
поделиться
        string s = "ABCDEFG";
        string t = "st";
        s = s.Remove(4, t.Length);
        s = s.Insert(4, t);
5
ответ дан Javed Akram 28 August 2018 в 02:18
поделиться

Я искал решение со следующими требованиями:

  1. использовать только одно однолинейное выражение
  2. использовать только встроенные методы системы (без настраиваемой утилиты)

Решение 1

Решение, которое мне больше всего подходит, это:

// replace `oldString[i]` with `c`
string newString = new StringBuilder(oldString).Replace(oldString[i], c, i, 1).ToString();

Используется StringBuilder.Replace(oldChar, newChar, position, count)

Решение 2

Другим решением, которое удовлетворяет моим требованиям, является использование Substring с конкатенацией:

string newString = oldStr.Substring(0, i) + c + oldString.Substring(i+1, oldString.Length);

Это тоже хорошо. Я угадал , он не так эффективен, как первый из них, из-за ненужной конкатенации строк. Но преждевременная оптимизация - это корень всех злых .

Итак, выберите тот, который вам больше всего нравится:)

0
ответ дан KFL 28 August 2018 в 02:18
поделиться

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

string str = "ABCDEFGHIJ";
str = str.Substring(0, 2) + "ZX" + str.Substring(5);
3
ответ дан MBU 28 August 2018 в 02:18
поделиться

ReplaceAt (int index, int length, string replace)

Вот метод расширения, который не использует 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 не нужно инициализировать и поскольку он использует более основные операции. Пожалуйста, поправьте меня, если я ошибаюсь. :)

27
ответ дан Nick Miller 28 August 2018 в 02:18
поделиться

Я считаю, что самым простым способом было бы это: (без stringbuilder)

string myString = "ABCDEFGHIJ";
char[] replacementChars = {'Z', 'X'};
byte j = 0;

for (byte i = 3; i <= 4; i++, j++)  
{                   
myString = myString.Replace(myString[i], replacementChars[j]);  
}

Это работает, потому что переменную типа string можно рассматривать как массив переменных char. Вы можете, например, обратиться ко второму символу строковой переменной с именем «myString» как myString [1]

-2
ответ дан Sfou 28 August 2018 в 02:18
поделиться

Лучше использовать String.substr().

Нравится это:

ReplString = GivenStr.substr(0, PostostarRelStr)
           + GivenStr(PostostarRelStr, ReplString.lenght());
1
ответ дан Shaikh Farooque 28 August 2018 в 02:18
поделиться

Еще один

    public static string ReplaceAtPosition(this string self, int position, string newValue)        
    {
        return self.Remove(position, newValue.Length).Insert(position, newValue); 
    }
2
ответ дан Stijn Van Antwerpen 28 August 2018 в 02:18
поделиться
string s = "ABCDEFGH";
s= s.Remove(3, 2).Insert(3, "ZX");
134
ответ дан V4Vendetta 28 August 2018 в 02:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: