Заменить подстроку в C#

#c# #asp.net

#c# #asp.net

Вопрос:

У меня есть следующая строка: «Последний запуск: 2011-10-03 13:58:54 (7-30 секунд назад) [статус]», и я хотел бы заменить «7-30 секунд» (это не фиксированная строка) другой сгенерированной мной строкой. Как я могу это сделать с помощью обработки строк в C #?

Комментарии:

1. Является ли строка образца статической?

2. Регулярное выражение.Заменить msdn.microsoft.com/en-us/library/xwewhkd1.aspx

3. Почему важно использовать старую строку вместо создания новой строки?

4. Это строка, которую вы создали, или ввод откуда-то еще? Если вы ее создали, почему бы не отформатировать ее правильно с первого раза? Некоторый код может помочь понять, что вы делаете.

5. Что у вас есть на данный момент?

Ответ №1:

 string str = "Last Run : (3m 4s ago) [status]";
str = str.Replace("3m 4s", "yournewstring");
  

Обновить :

Ссылка: ответ Кэша.

Если время не фиксировано, оно может быть в часах, днях, минутах и секундах, тогда лучшим выбором будет регулярное выражение, поскольку это делается с помощью Kash. Вы можете сделать это, как показано ниже :

 string str = "Last Run: 2011-10-03 13:58:54 (7m 30s  ago) [status]";
string replacement = "test";
string pattern = @"((. ?)s ago)";
Regex rgx = new Regex(pattern);
string result = rgx.Replace(str, "("   replacement   " ago)");
MessageBox.Show(result);
  

Комментарии:

1. Исходя из вопроса, «3m 4s» не исправлено, следовательно, это не сработает. Возможно, нам придется использовать String . Замените (или регулярное выражение), используя шаблон для остальной части строки.

2. @Kash: это не было упомянуто OP в вопросе в то время, когда я отвечал.

3. Звучит здорово, я не понимал, что этот ответ был введен до обновления вопроса (хотелось бы, чтобы был лучший способ показать временную шкалу изменений и ответов на вопросы — другое дело для metastackoverflow). Я удалил свой понижающий голос.

Ответ №2:

Вам следует рассмотреть возможность использования String .Формат вместо этого для этого

 string result = String.Format("Last Run : ({0} ago) [status]", theTime);
  

Это только в том случае, если у вас есть контроль над рассматриваемой строкой.

Ответ №3:

Для наиболее удобного способа решения этой проблемы используйте комбинацию регулярных выражений и строк.Замените, как показано в приведенном ниже коде. Я предполагаю, что у вас нет доступа к генерации этой входной строки (последний запуск: 2011-10-03 13:58:54 (7m 30s назад) [статус]).

В основном он состоит из 3 этапов:

Найдите шаблон:

Я использую фигурные скобки во входной строке и «назад» в качестве шаблона, чтобы определить длительность, которую вам нужно заменить. «((. ?) s назад)» — это используемый шаблон. Он использует ленивый квантификатор «?», чтобы гарантировать минимальное совпадение вместо жадного совпадения. Может быть неприменимо к вашему примеру здесь, но помогает, если метод будет повторно использоваться в других сценариях.

Создайте группу обратных ссылок, чтобы получить точную подстроку 7m 30s

Регулярное выражение.Match использует шаблон и создает группу, которая будет содержать «7m 30s». Пожалуйста, обратите внимание, что 1-я группа — это полное совпадение. 2-я группа — это то, что будет в фигурных скобках, указанных в шаблоне, который в данном случае равен «7m 30s». Это должно быть хорошо, даже если позже вы получите длительность, которая выглядит так: «Последний запуск: 2011-10-03 13:58:54 (1d 3h 20m 5s назад) [статус]»

Заменить вхождение

Затем строка.Replace используется для замены этой подстроки вашей заменяющей строкой. Чтобы сделать его более универсальным, метод Replace, приведенный ниже, будет принимать входную строку, строку замены, шаблон и номер группы обратной ссылки (в данном случае только одну группу), чтобы вы могли повторно использовать этот метод для разных сценариев.

     private void button1_Click(object sender, EventArgs e)
    {
        string inputString = "Last Run: 2011-10-03 13:58:54 (7m 30s  ago) [status]";
        string replacementString = "Blah";
        string pattern = @"((. ?)s ago)";
        int backreferenceGroupNumber = 1;
        string outputString = Replace(inputString, replacementString, pattern, backreferenceGroupNumber);
        MessageBox.Show(outputString);
    }

    private string Replace(string inputString, string replacementString, string pattern, int backreferenceGroupNumber)
    {
        return inputString.Replace(Regex.Match(inputString, pattern).Groups[backreferenceGroupNumber].Value, replacementString);
    }
  

Это было протестировано, и оно выводит «Последний запуск: 2011-10-03 13:58:54 (Бла назад) [статус]».

Примечания:

  • Вы можете соответствующим образом изменить метод Replace для проверок IsNullOrEmpty и / или проверок null.
  • button1_Click был моим образцом обработчика событий, который я использовал для его тестирования. Вы можете извлечь часть этого в своем основном коде.
  • Если у вас есть доступ к генерации входной строки, то вы можете управлять частью длительности во время генерации самой строки вместо того, чтобы использовать этот код для замены чего-либо.

Комментарии:

1. это отличный ответ, но я нашел простое решение, как указано ниже в разделе ответов.

Ответ №4:

Вы можете либо использовать String.Replace метод для своей строки, например:

 var myString = "Last Run : (3m 4s ago) [status]";
var replacement = "foo";
myString = myString.Replace("3m 4s ago", replacement);
  

Или, возможно, вы хотите использовать регулярное выражение, например:

 var rgx = new Regex(@"d m d s ago");
myString = rgx.Replace(myString, replacement);
  

Приведенное выше регулярное выражение является всего лишь примером и не проверялось.

Комментарии:

1. Первое решение не будет работать, так как «3m 4s» не является постоянным и будет меняться.

2. Второе решение не будет работать с шаблоном » d m d s назад», более того, он может иметь часовой и дневной компонент, поскольку он показывает продолжительность с момента последнего запуска. Следовательно, второе решение также не будет работать.

Ответ №5:

Вы можете попробовать это :

         string s = "Last Run : (3m 4s ago) [status]";
        s = s.Replace("3m 4s", myString);
  

Комментарии:

1. @Kash : это не было указано, когда я отвечал 😉

2. Ах! Извините за это. Я удалю свой понижающий голос после истечения 2-часового лимита.

3. Привет, Себ, не могли бы вы отредактировать свой ответ, указав по крайней мере 6 символов, чтобы я мог удалить свой downvote (StackOverflow не позволяет мне делать это без редактирования ответа).

Ответ №6:

Используйте строку.Для этого используйте функцию Replace(), а также смотрите приведенный ниже код.

 stirng YourString = "Last Run : (3m 4s ago) [status]";
YourString = YourString.Replace("3m 4s","Your generated String");
  

Комментарии:

1. Хорошо, @Downvoters должен сообщить причину, прежде чем голосовать против. Имейте мужество назвать причину.

2. Извините за это, я проголосовал против, потому что OP упомянул, что длительность не является статической, поэтому ваш код не будет работать. Однако я считаю, что ваш ответ был введен до того, как было выполнено редактирование вопроса. я хотел бы удалить свой downvote, но stackoverflow нуждается в редактировании этого ответа (по крайней мере, 6 символов), прежде чем я смогу удалить свой downvote. Не могли бы вы, пожалуйста, изменить свой ответ, чтобы я мог это сделать. Спасибо

Ответ №7:

 string input = "Last Run: 2011-10-03 13:58:54 (7m 30s  ago) [status] ";
string pattern = @"(d h d m d s|d m d s|d s)";
string replacement = "yay";
Regex rgx = new Regex(pattern);
string result = rgx.Replace(input, replacement);

Console.WriteLine("Original String: {0}", input);
Console.WriteLine("Replacement String: {0}", result);  
  

Это пример http://msdn.microsoft.com/en-us/library/xwewhkd1.aspx просто изменил входные данные и шаблон…

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

Ответ №8:

Как насчет:

 Regex.Replace(yourString, @"(. )", string.Format("({0} ago)", yourReplacement));
  

Немного перебор, но должен работать и прост.

Объяснение

@"(. )" сопоставит полную пару скобок с чем-либо между ними (поэтому убедитесь, что у вас будет только одна пара скобок, иначе это не сработает).

string.Format("({0} ago)", yourReplacement) вернет «(yourReplacement назад)»

Ответ №9:

Не используйте string .Заменить. Просто выведите новую строку:

 TimeSpan elapsed = DateTime.Now.Subtract(lastRun);
string result =  string.Format("Last Run: {0} ({1} ago) [status]", lastRun, elapsed.ToString("%m'm '%s's'"));
  

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

Ответ №10:

this.lastrun это строка, как я определил в вопросе.

 this.lastRun = this.lastRun.Replace(this.lastRun.Substring(lastRun.IndexOf("(")   1, (lastRun.IndexOf(")") - lastRun.IndexOf("(") - 1)) , retstr   " ago");