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

C# 使用格式模板解析字符串?,c#,.net,string,C#,.net,String,如果我可以使用 string.Format("my {0} template {1} here", 1, 2) 我是否可以反转此过程-我提供模板和填充字符串,.net返回arg0、arg1等?一种方法是使用正则表达式。例如,您可以执行以下操作: Regex regex = new Regex("^my (.*?) template (.*?) here$"); Match match = regex.Match("my 53 template 22 here"); string arg0 =

如果我可以使用

string.Format("my {0} template {1} here", 1, 2)

我是否可以反转此过程-我提供模板和填充字符串,.net返回arg0、arg1等?

一种方法是使用正则表达式。例如,您可以执行以下操作:

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[];
} 
该方法非常简单,存在许多问题,但它基本上会在格式表达式中找到任何占位符,并在源字符串中找到相应的文本。它将为您提供从左到右列出的占位符对应的值,而不参考序号或占位符中指定的任何格式。可以添加此功能


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

的任何特殊字符,使用正则表达式解析组匹配项

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

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

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

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;
}
private List reverseStringFormat(字符串模板,字符串str)
{
//韩德尔正则表达式特殊字符。
template=Regex.Replace(template,@“[\\^\$\.\\\\\?\*\+\(\)]”,m=>“\\”
+m.价值);
string pattern=“^”+Regex.Replace(模板,@“{[0-9]+\}”,“(.*)”+“$”;
正则表达式r=新正则表达式(模式);
匹配m=r.Match(str);
List ret=新列表();
对于(int i=1;i
String.Format在一般情况下不可反转

如果您正好有一个{0},那么实际上可以编写至少提取值的字符串表示形式的泛型代码。您绝对不能将其反转以生成原始对象

样本:

  • 多个参数:
    string.Format(“my{0}{1}”、“aa”、“aaa”)
    生成“myaaaaa”,尝试反转
    字符串。ReverseFormat(“my{0}{1}”,“myaaaaa”)
    必须决定如何在没有任何信息的情况下将“aaaaa”部分拆分为2

  • 无法转换为数据类型
    string.Format(“{0:yyyy}”,DateTime.Now)结果在2011年,大部分关于价值本身的信息丢失


  • 这听起来像是一个使用正则表达式的例子,我想…我很好奇是否可以避免使用正则表达式。似乎两个对象共享一个模板,并且只使用该模板填充和反填充字符串。会很优雅。有没有办法避免正则表达式?net是否有一种内置机制,可以使用参数为{}格式的模板来解析字符串?我还没有见过这种情况。我想在处理这些模板时,您可以将“{0}”自动替换为“(.*)”。看看上面攀登的答案。你能确认没有办法按原样使用字符串模板(不编写自定义扩展方法)吗?见上面的评论。我不知道,但这并不意味着什么。但我可以看到编写一个方法,它将采用格式和适当大小的对象数组,解析格式并将其转换为适当的正则表达式,进行匹配,然后用结果值填充对象数组。是的……就像上面@grampage的解决方案一样。谢谢!希望在.net中内置一些东西,但似乎没有。这是一个很好的解决方案,很好的解决方案。为了确保生成的模式有效,您必须在创建模式之前替换所有特殊的正则表达式字符:
    template=regex.replace(template,@“[\\\^\$\.\\\\\\?\*\+\(\)]”,m=>“\\\”+m.Value)
    @Elian Good call。此外,还应注意,在Alexei所述的情况下,这不会再现正确的结果。请在转义字符中添加方括号:
    template=Regex.Replace(template,@“[\\^\$\.\\\\?\*\+\(\)\[\]]”,m=>“\\\\”+m.Value)
    
    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;
    }