简体   繁体   中英

Replace a substring in C#

I have the following string, "Last Run: 2011-10-03 13:58:54 (7m 30s ago) [status]" and I would like to replace "7m 30s" (it is not a fixed string) with another string I have generated. How can I do that with string manipulation in C#?

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

UPDATE :

Ref : Kash's answer.

If time is not fixed, it might be in hour,day, minute and second then regular expression is best choice as it's done by Kash. You can do it like below :

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);

You should consider using String.Format instead for this

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

This is only if you have control over the string in question.

You can try this :

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

Use String.Replace() function for that and also see the below code.

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

You can either use the String.Replace method on your string like:

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

Or probably you want to use a regular expression like:

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

The regular expression above is just an example and not tested.

For the most convenient way to resolve this, use a combination of RegEx and String.Replace like the below code. I am assuming you do not have access to the generation of this input string (Last Run: 2011-10-03 13:58:54 (7m 30s ago) [status]).

It basically has 3 stages:

Locate the pattern:

I am using the braces in the input string and "ago" as the pattern to locate the duration that you need to replace. "((.+?)\\s+ago)" is the pattern used. It uses the lazy quantifier "?" to ensure it does minimal matching instead of a greedy match. May not be applicable to your example here but helps if the method will be reused in other scenarios.

Create the backreference group to get the exact substring 7m 30s

Regex.Match uses the pattern and creates the group that will contain "7m 30s". Please note the 1st group is the entire match. The 2nd group is what will be in the braces specified in the pattern which in this case is "7m 30s". This should be good even if later you get a duration that looks like: "Last Run: 2011-10-03 13:58:54 (1d 3h 20m 5s ago) [status]"

Replace the occurence

Then String.Replace is used to replace this substring with your replacement string. To make it more generic, the method Replace below will accept the inputstring, the replacement string, the pattern and the group number of the backreference (in this case only one group) so that you can reuse this method for different scenarios.

    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);
    }

This has been tested and it outputs "Last Run: 2011-10-03 13:58:54 (Blah ago) [status]".

Notes:

  • You can modify the Replace method appropriately for IsNullOrEmpty checks and/or null checks.
  • The button1_Click was my sample eventhandler that I used to test it. You can extract part of this in your core code.
  • If you do have access to the generation of the input string, then you can control the duration part while you are generating the string itself instead of using this code to replace anything.
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);  

This is the example of http://msdn.microsoft.com/en-us/library/xwewhkd1.aspx just changed the input and the pattern...

The pattern can be improved because maybe in the input string you only receive the seconds or the hours, minutes and seconds.... Kinda of an improvement in the regex

How about:

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

A bit brute force but should work and is simple.

Explanation

@"\\(.+\\)" will match a complete pair of brackets with anything between them (so make sure you will only ever have one pair of brackets else this won't work).

string.Format("({0} ago)", yourReplacement) will return "(yourReplacement ago)"

Don't use string.Replace. Just output a new string:

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

This assumes that the lastRun variable is populated with the last run time.

this.lastrun是我在问题中定义的字符串。

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM