C# 替换C中的子字符串

C# 替换C中的子字符串,c#,asp.net,C#,Asp.net,我有以下字符串,最后一次运行:2011-10-03 13:58:54 7m 30s前[状态],我想用我生成的另一个字符串替换7m 30s,它不是固定字符串。在C语言中,如何使用字符串操作来实现这一点 string str = "Last Run : (3m 4s ago) [status]"; str = str.Replace("3m 4s", "yournewstring"); 更新: 参考:卡什的回答 若时间不是固定的,那个么它可能是以小时、天、分和秒为单位的,正则表达式是最好的选择,因

我有以下字符串,最后一次运行:2011-10-03 13:58:54 7m 30s前[状态],我想用我生成的另一个字符串替换7m 30s,它不是固定字符串。在C语言中,如何使用字符串操作来实现这一点

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);
您可以尝试以下方法:

        string s = "Last Run : (3m 4s ago) [status]";
        s = s.Replace("3m 4s", myString);
你应该考虑使用这个/P>
string result = String.Format("Last Run : ({0} ago) [status]", theTime);
仅当您可以控制所讨论的字符串时,才能执行此操作。

使用函数进行此操作,并查看以下代码

stirng YourString = "Last Run : (3m 4s ago) [status]";
YourString = YourString.Replace("3m 4s","Your generated String");
this.lastRun = this.lastRun.Replace(this.lastRun.Substring(lastRun.IndexOf("(") + 1, (lastRun.IndexOf(")") - lastRun.IndexOf("(") - 1)) , retstr + " ago");
您可以对字符串使用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);
上面的正则表达式只是一个示例,没有经过测试

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);  
这是刚刚更改输入和模式的示例

模式可以改进,因为可能在输入字符串中您只接收秒或小时、分钟和秒。。。。正则表达式有一点改进

那么:

Regex.Replace(yourString, @"\(.+\)", string.Format("({0} ago)", yourReplacement));
有点暴力,但应该工作,是简单的

解释

@\.+\将匹配一对完整的括号和括号之间的任何内容,因此请确保只有一对括号,否则这将不起作用


string.Format{0}之前,您的替换将返回您的替换日期

不要使用string.Replace。只需输出一个新字符串:

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

这假设lastRun变量是用上次运行时间填充的。

要解决此问题,最方便的方法是使用RegEx和String的组合。请按照下面的代码进行替换。我假设您没有权限生成此输入字符串上次运行时间:2011-10-03 13:58:54 7m 30秒前[状态]

它基本上有三个阶段:

找到模式:

我使用输入字符串和ago中的大括号作为模式来定位需要替换的持续时间..+\s+ago是使用的模式。 它使用惰性量词?以确保它执行最小匹配,而不是贪婪匹配。可能不适用于此处的示例,但如果该方法将在其他场景中重用,则会有所帮助

    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);
    }
创建反向引用组以获得精确的子字符串7m 30s

Match使用该模式并创建包含7m 30的组。请注意,第一组是整场比赛。第二组是模式中指定的支架,在本例中为7m 30s。这应该是好的,即使以后你得到的持续时间看起来是:2011-10-03 13:58:54 1d 3h 20m 5s前[状态]

替换发生的事件

然后使用String.Replace将此子字符串替换为替换字符串。 为了使其更通用,下面的Replace方法将只接受backreference的inputstring、replacement string、pattern和组号(在本例中为一个组),以便您可以在不同的场景中重用此方法

    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 Blah ago[状态]

注:

您可以为IsNullOrEmpty适当地修改Replace方法 检查和/或空检查。 button1\u Click是我用来测试的示例eventhandler 信息技术您可以在核心代码中提取其中的一部分。 如果您确实有权生成输入字符串,那么您可以在生成字符串时控制持续时间部分,而不是使用此代码替换任何内容。 this.lastrun是我在问题中定义的字符串

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

示例字符串是静态的吗?Regex.Replace为什么使用旧字符串而不是创建新字符串很重要?这是您创建的字符串还是来自其他地方的输入?如果您创建了它,为什么不在第一次正确格式化它?一些代码可能有助于理解你在做什么。到目前为止你有什么?基于这个问题,3m 4s不是固定的,因此这将不起作用。我们可能不得不使用String.Replace或Regex来替换字符串的其余部分。@Kash:在我回答问题时,OP没有提到它。听起来不错,我没有意识到这个答案是在问题更新之前输入的,我希望有更好的方式来显示问题编辑和答案的时间线-metastackoverflow的另一件事。我已经删除了我的否决票。第一个解决方案将不起作用,因为3m 4s不是常数,并且会发生变化。第二个解决方案将不适用于\d+m\d+s之前的模式,而且这可能有一个小时和一天的组成部分,因为它显示了上次运行的持续时间。因此,第二种解决方案也不起作用。@Kash:我回答时没有具体说明-啊!!很抱歉。我将在2小时限制后删除我的下一票。嗨,Seb,你能用至少6个字符编辑你的答案,这样我就可以删除我的下一票吗?StackOverflow不允许我在没有答案编辑的情况下这样做。好的,@downvotters应该在d之前告诉我原因
自己投票。有勇气说一个原因。很抱歉,我投了反对票,因为OP提到持续时间不是静态的,因此您的代码将无法工作。不过,我相信你的答案是在编辑问题之前提交的。我想删除我的否决票,但stackoverflow需要编辑此答案至少6个字符,然后才能删除我的否决票。你能改变你的答案吗?这样我就可以做了。谢谢你的回答,但我发现解决方法很简单,正如下面在回答部分所贴的。