字符串中的正则表达式替换

时间:2017-09-12 12:47:52

标签: c# regex

我有字符串对:

"foo" + "bar"

我想要做的是修改s_1 : "He graduated in 1994 with 32 courses" s_2 : "I graduated in 0000 with 00 courses" ,以便将s_2更改为0000,将1994更改为32.

00

基本上,modified_s_2 : "I graduated in 1994 with 32 courses" 表示它会与0000...n_times...0n位的数字字符串匹配。

我可以通过循环实现这一点。 我正在寻找有效的实施。我认为正则表达式的实现很容易。

注意:字符串中可以有任意s_1个数字,每个数字可以包含任意数量的数字。

3 个答案:

答案 0 :(得分:2)

我认为你的意思是:

var s_1 = "He graduated in 1994 with 32 courses";
var s_2 = "I graduated in 0000 with 00 courses 0000";

//// I'll find combination of '0's to be replaced
var regexes =
    Regex.Matches(s_2, @"\b0+\b")
        .OfType<Match>()
        .Select(c => new { c.Value, Reg = new Regex(c.Value.Replace("0", @"\d")) })
        .ToList();

//// now I replace each '0's combination with first match 
var curS1 = s_1;
foreach (var regex in regexes)
{
    var s1Value = regex.Reg.Match(curS1).Value;
    curS1 = regex.Reg.Replace(curS1, "", 1);     //// I remove first match of s_1 to don't matched again
    s_2 = new Regex(regex.Value).Replace(s_2, s1Value, 1);
}

[ C# Demo ]

测试用例可以是:

var s_1 = "He graduated in 1994 with 32 courses then 254 for 1998";
var s_2 = "I graduated in 0000 with 00 courses then 000 for 0000";

结果将是:

I graduated in 1994 with 32 courses then 254 for 1998

答案 1 :(得分:0)

希望这可以让你开始,因为你正在寻找正则表达式。您可以将其修改为循环,无论您使用何种类型的“字符串对”。

这就是正则表达式在视觉上的外观:Regex101(这就是我们执行下面的.Trim()的原因)。我更改了它,因此它与该特定示例的联系较少,可以在不同的地方使用各种数字

var s_1 = "He graduated number 1 in class in 1900 with 20 courses over the course of 12 weeks";
var s_2 = "I graduated number 0 in class in 0000 with 00 courses over the course of 00 weeks";

// Finds the matches in s_1 with the year and the number of courses
// The spaces are important in the regex so we match properly
var regex = new Regex("( \\d{1,} )");
var matches = regex.Matches(s_1);

var lastIndex = 0; // This is necessary so we aren't replacing previously replaced values
foreach(var match in matches.Cast<Match>())
{
    // The matched value, removing extra spaces
    var trimmedMatch = match.Value.Trim();

    // The n-length 0 string in s_2
    var zeroString = new String('0', trimmedMatch.Length);

    // A simpler way to replace a string within a string
    var sb = new StringBuilder(s_2);
    var replaceIndex = s_2.IndexOf(zeroString, lastIndex);
    sb.Remove(replaceIndex, zeroString.Length);
    sb.Insert(replaceIndex, trimmedMatch);

    s_2 = sb.ToString();

    // This is necessary otherwise we could end up overwriting previously done work
    lastIndex = replaceIndex + zeroString.Length;
}

答案 2 :(得分:0)

Disclamer:如果patern字符串"00"不在字符串中,我会让你处理错误。

由于我没有关于您在实施中遇到的实际性能问题的信息,但您可以计算每个输入和模板输出中的数字位数,以便了解它们是否匹配。

string input = "He graduated in 1994 with 32 coursesHe graduated in 1994 with 32 coursesHe graduated in 1994 with 32 courses ";            
string ouput = "He 0000 with 00 He in 0000 with 00 He in 0000 with 00";
string regex = @"(\d+)";

var matches = Regex.Matches(input, regex).Cast<Match>();
var tempSB = new StringBuilder(ouput);
foreach(var i in matches)
{
    var strI = i.Value;
    var strILength = strI.Length;

    var template = new string('0', strILength );
    var index = ouput.IndexOf(template);    // if (index ==-1) exception;

    tempSB.Remove(index, strILength);
    tempSB.Insert(index, strI);

    ouput = tempSB.ToString();
}

对于50Mo输入,大约需要10秒。多数民众赞成合理。