使用格式模板解析字符串?

时间:2011-03-17 22:39:48

标签: c# .net string

4 个答案:

答案 0 :(得分:30)

没有优雅的方法来反转格式化的字符串。但是如果你想要一个简单的功能,你可以尝试这个。

private List<string> reverseStringFormat(string template, string str)
{
     //Handels regex special characters.
    template = Regex.Replace(template, @"[\\\^\$\.\|\?\*\+\(\)]", m => "\\" 
     + m.Value);

    string pattern = "^" + Regex.Replace(template, @"\{[0-9]+\}", "(.*?)") + "$";

    Regex r = new Regex(pattern);
    Match m = r.Match(str);

    List<string> ret = new List<string>();

    for (int i = 1; i < m.Groups.Count; i++)
    {
        ret.Add(m.Groups[i].Value);
    }

    return ret;
}

答案 1 :(得分:7)

String.Format在一般情况下是不可逆的。

如果只有一个{0},则可以编写至少提取值的字符串表示形式的通用代码。你绝对不能反转它来制作原始物品。

样品:

  1. 多个参数:string.Format("my{0}{1}", "aa", "aaa");产生“myaaaaa”,反转string.ReverseFormat("my{0}{1}", "myaaaaa")必须决定如何在没有任何信息的情况下拆分2中的“aaaaa”部分。

  2. 无法逆转数据类型string.Format("{0:yyyy}", DateTime.Now);导致2011年,大部分有关价值的信息都会丢失。

答案 2 :(得分:2)

执行此操作的一种方法是正则表达式。您可以这样做:

Regex regex = new Regex("^my (.*?) template (.*?) here$");
Match match = regex.Match("my 53 template 22 here");
string arg0 = match.Groups[1].Value;    // = "53"
string arg1 = match.Groups[2].Value;    // = "22"

根据这种技术编写一个扩展方法来完成你想做的事情并不困难。

只是为了好玩,这是我的第一次天真的尝试。我没有测试过这个,但它应该很接近。

public static object[] ExtractFormatParameters(this string sourceString, string formatString)
{
    Regex placeHolderRegex = new Regex(@"\{(\d+)\}");
    Regex formatRegex = new Regex(placeHolderRegex.Replace(formatString, m => "(<" + m.Groups[1].Value + ">.*?)");
    Match match = formatRegex.Match(sourceString);
    if (match.Success)
    {
        var output = new object[match.Groups.Count-1];
        for (int i = 0; i < output.Length; i++)
            output[i] = match.Groups[i+1].Value;
        return output;
    }
    return new object[];
} 

这将允许你做

object[] args = sourceString.ExtractFormatParameters("my {0} template {1} here");

该方法非常幼稚且存在许多问题,但它基本上会在格式表达式中找到任何占位符,并在源字符串中找到相应的文本。它将为您提供与从左到右列出的占位符对应的值,而不引用序号或占位符中指定的任何格式。可以添加此功能。

另一个问题是格式字符串中的任何特殊正则表达式字符都会导致方法失效。需要对formatRegex进行更多处理才能转义属于formatString的任何特殊字符。

答案 3 :(得分:2)

使用正则表达式解析组匹配。

Regex.Match("my (.*) template (.*) here", theFilledInString);

我没有打开VS,所以我无法验证我的方法名称是否正确,但你知道我的意思。通过使用paranthesis,返回的匹配结果将包含包含您提取的匹配的组[0]和组[1]。