使用Regex .NET样式进行可变扩展

时间:2009-09-02 01:26:31

标签: c# .net regex string

我正在开发一个小应用程序,需要用它们的值替换字符串中的.NET样式“变量”。下面给出一个例子:

替换

“{d} / {MM} / {YYYY}”

。通过 “31/12/2009”

我决定使用正则表达式来查找“{var}”的出现次数,但我不太清楚如何正确处理它。

5 个答案:

答案 0 :(得分:4)

如果你打算使用正则表达式,并且你有一个已知模式,那么使用匹配求值程序方法而不是多次调用replace就不会简单得多:

void Main() // run this in LinqPad
{
    string text = "I was here on {D}/{MMM}/{YYYY}.";
    string result = Regex.Replace(text, "{[a-zA-Z]+}", ReplaceMatched);

    Console.WriteLine(result);
}

private string ReplaceMatched(Match match)
{
    if( match.Success )
    {
        switch( match.Value )
        {
            case "{D}":
                return DateTime.Now.Day.ToString();
            case "{YYYY}":
                return DateTime.Now.Year.ToString();
            default:
                break;
        }
    }
    // note, early return for matched items.

    Console.WriteLine("Warning: Unrecognized token: '" + match.Value + "'");
    return match.Value;
}

给出结果

Warning: Unrecognized token: '{MMM}'
I was here on 2/{MMM}/2009.

显然没有完全实现。

查看LinqPadExpresso

等正则表达式工具

答案 1 :(得分:1)

正则表达式非常强大,但也需要很多开销。使用类似inputString.Replace("{var}", value)的东西可能更简单:

void Foo()
{
    string s = "{D}/{MM}/{YYYY}";
    s = ReplaceTokenInString(s, "{D}", "31");
    s = ReplaceTokenInString(s, "{MM}", "12");
    s = ReplaceTokenInString(s, "{YYYY}", "2009");
}

string ReplaceTokenInString(string input, string token, string replacement)
{
    input.Replace(token, replacement);
}

答案 2 :(得分:0)

以下是我在日志记录实用程序中使用的一些代码,它几乎完全符合您的要求,但格式略有不同:

    Regex rgx = new Regex("{([Dd]:([^{]+))}");

    private string GenerateTrueFilename()
    {
        // Figure out the new file name
        string lfn = LogFileName;
        while (rgx.IsMatch(lfn))
        {
            Match m = rgx.Matches(lfn)[0];
            string tm = m.Groups[1].Value;
            if (tm.StartsWith("D:"))
            {
                string sm = m.Groups[2].Value;
                string dts = DateTime.Now.ToString(sm);
                lfn = lfn.Replace(m.Groups[0].Value, dts);
            }
        }

        return lfn;
    }

rgx定义了格式,目前实际上只有一种格式:

d:{datestring}

LogFileName是在代码中其他位置定义的变量,但具有默认值:

LogFileName = "LogFile.{D:yyyy-MM-dd}.log"

所以希望您可以从中了解如何在需要时继续使用其他变量。

答案 3 :(得分:0)

如果你专门做日期,你应该考虑使用format string。显然,如果你做得更多,这对你没有帮助。

答案 4 :(得分:0)

我已经使用Regex并使用StringBuilder完成了它。我在源字符串中找到匹配项并附加字符串的块并评估匹配。

StringBuilder text = new StringBuilder(snippet.Length * 2);
Regex pattern = new Regex("\\{[A-Za-z]+\\}");
MatchCollection matches = pattern.Matches(snippet);
if (matches.Count == 0) return snippet;

int from = 0;
foreach (Match match in matches)
{
    text.Append(snippet.Substring(from, match.Index - from));
    string variable = snippet.Substring(match.Index + 1, match.Length - 2);
    text.Append(EvaluateVariable(variable));
    from = match.Index + match.Length;
}
text.Append(snippet.Substring(from));
return text.ToString();