C# 格式字符串包含“{”时的 String.Format 异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1118529/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 08:37:33  来源:igfitidea点击:

String.Format exception when format string contains "{"

c#.netstring.format

提问by George2

I am using VSTS 2008 + C# + .Net 2.0. When executing the following statement, there is FormatException thrown from String.Format statement, any ideas what is wrong?

我使用的是 VSTS 2008 + C# + .Net 2.0。执行以下语句时,String.Format 语句抛出FormatException,有什么问题吗?

Here is where to get the template.html I am using. I want to format this part m={0} in template.html.

这是获取我正在使用的 template.html 的位置。我想在 template.html 中格式化这部分 m={0}。

    string template = String.Empty;
    using (StreamReader textFile = new StreamReader("template.html"))
    {
        template = textFile.ReadToEnd();
        String.Format(template, "video.wmv");
    }

http://www.mediafire.com/download.php?u4myvhbmmzg

http://www.mediafire.com/download.php?u4myvhbmmzg

EDIT 1:

编辑 1:

Here is the content for my template.html,

这是我的 template.html 的内容,

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<!-- saved from url=(0014)about:internet -->
<head>
    <title>Silverlight Project Test Page </title>

    <style type="text/css">
    html, body {
        height: 100%;
        overflow: auto;
    }
    body {
        padding: 0;
        margin: 0;
    }
    #silverlightControlHost {
        height: 100%;
    }
    </style>

    <script type="text/javascript">
        function onSilverlightError(sender, args) {

            var appSource = "";
            if (sender != null && sender != 0) {
                appSource = sender.getHost().Source;
            } 
            var errorType = args.ErrorType;
            var iErrorCode = args.ErrorCode;

            var errMsg = "Unhandled Error in Silverlight 2 Application " +  appSource + "\n" ;

            errMsg += "Code: "+ iErrorCode + "    \n";
            errMsg += "Category: " + errorType + "       \n";
            errMsg += "Message: " + args.ErrorMessage + "     \n";

            if (errorType == "ParserError")
            {
                errMsg += "File: " + args.xamlFile + "     \n";
                errMsg += "Line: " + args.lineNumber + "     \n";
                errMsg += "Position: " + args.charPosition + "     \n";
            }
            else if (errorType == "RuntimeError")
            {           
                if (args.lineNumber != 0)
                {
                    errMsg += "Line: " + args.lineNumber + "     \n";
                    errMsg += "Position: " +  args.charPosition + "     \n";
                }
                errMsg += "MethodName: " + args.methodName + "     \n";
            }

            throw new Error(errMsg);
        }
    </script>
</head>

<body>
    <!-- Runtime errors from Silverlight will be displayed here.
    This will contain debugging information and should be removed or hidden when debugging is completed -->
    <div id='errorLocation' style="font-size: small;color: Gray;"></div>

    <div id="silverlightControlHost">
        <object data="data:application/x-silverlight," type="application/x-silverlight-2" width="500" height="240">
            <param name="source" value="ClientBin/VideoPlayer.xap"/>
            <param name="onerror" value="onSilverlightError" />
            <param name="background" value="white" />
            <param name="initParams" value="cc=true,markers=true,m={0}" />
            <a href="http://go.microsoft.com/fwlink/?LinkID=115261" style="text-decoration: none;">
                <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
            </a>
        </object>
        <iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>
    </div>
</body>
</html>

thanks in avdance, George

感谢 avdance,乔治

采纳答案by Marc Gravell

At a guess, the html contains javascript or another source of braces ({and }) which would all need doubling (to {{and }}) to be usable with string.Format. I expect a different (more obvious) token may be in order, i.e. %%FILENAME%%. Then use either regex or string.Replace.

猜测,html 包含 javascript 或其他大括号({})来源,它们都需要加倍(到{{}})才能与string.Format. 我希望一个不同的(更明显的)令牌可能是有序的,即%%FILENAME%%. 然后使用正则表达式或string.Replace.

If you have a single tag, string.Replaceis fine; if you have lots, there are tricks with regex and MatchEvaluatorthat may be helpful - like sobut with a different regex pattern.

如果你只有一个标签,那string.Replace很好;如果你有很多,有正则表达式的技巧,MatchEvaluator这可能会有所帮助 -就像这样,但使用不同的正则表达式模式。



Update after the example html added: I would definitely use a different token; at the most basic level:

添加示例 html 后更新:我肯定会使用不同的令牌;在最基本的层面上:

<param name="initParams" value="cc=true,markers=true,m=%%FILENAME%%" />

and

template = template.Replace("%%FILENAME%%", "video.wmv");

回答by Frederik Gheysels

Wat are the contents of the 'template' variable ?

Wat 是“模板”变量的内容吗?

Difficult to say what 's wrong with your code, but presumably, the template variable does not contain a string which as a place-holder. (Like "this is some string {0}").

很难说您的代码有什么问题,但据推测,模板变量不包含作为占位符的字符串。(例如“这是一些字符串 {0}”)。

I think that you should make use of the tools your IDE provides: debug the code, use watches to inspect the contents of the template variable.

我认为您应该使用您的 IDE 提供的工具:调试代码、使用监视来检查模板变量的内容。

回答by Omar Kooheji

Whats in the template file?

模板文件里有什么?

if there are curly brackets that are not of the format {int} or there are more than there are arguments for the format statement, it'll throw an exception.

如果有不是格式 {int} 的大括号或者格式语句的参数多于参数,它会抛出异常。

What is the message in the exception?

异常中的消息是什么?

It's your Css thats doing it. As somoene else mentioned you'll need to doa regex replace, or a bunch of String.Replace commands in a row mark you variables with %%VARIABLE_NAME%% and use string replacement to replace them

这是你的 CSS 做的。正如其他人提到的,你需要做一个正则表达式替换,或者一堆 String.Replace 命令在一行中用 %%VARIABLE_NAME%% 标记你的变量并使用字符串替换来替换它们

回答by Matt Howells

Your template contains {and }characters which need to be escaped, otherwise they confuse String.Format. Escape them using {{and }}. Alternatively, use a different mechanism such as String.Replace.

您的模板包含{}需要转义的字符,否则它们会混淆String.Format. 使用{{和转义它们}}。或者,使用不同的机制,例如String.Replace

回答by codeape

string.Format() does not handle {and }in the format string. You need to replace {with {{and }with }}everywhere in your template.htmlfile. Except for the single place where you use the {0}placeholder.

string.Format() 不处理{}格式字符串。您需要更换{{{}}}无处不在的template.html文件。除了您使用{0}占位符的单个地方。

Not very elegant.

不是很优雅。

Instead, consider using a template engine. See http://csharp-source.net/open-source/template-enginesfor some suggestions.

相反,请考虑使用模板引擎。有关一些建议,请参阅http://csharp-source.net/open-source/template-engines

The next-best solution is to use regexes (with MatchEvaluator) or string.Replace(), as suggested by other answers.

次佳解决方案是使用正则表达式(使用 MatchEvaluator)或 string.Replace(),正如其他答案所建议的那样。

Edit:

编辑:

Here's an example using the StringTemplate template engine:

这是使用 StringTemplate 模板引擎的示例:

StringTemplate htmlpage = new StringTemplate(File.ReadAllText("template.html"));
htmlpage.SetAttribute("content", "video.wmv");
Console.WriteLine(htmlpage.ToString());

Change a single line in your template.htmlfile:

更改template.html文件中的一行:

from:

从:

<param name="initParams" value="cc=true,markers=true,m={0}" />

to:

到:

<param name="initParams" value="cc=true,markers=true,m=$content$" />

When the template engine encounters $content$in the template, it replaces it with the value of the 'content' attribute that you set using code.

当模板引擎$content$在模板中遇到时,它会将其替换为您使用代码设置的“内容”属性的值。

Using StringTemplate, you can do simple looping and conditionals within your template. See the documentation.

使用 StringTemplate,您可以在模板中执行简单的循环和条件语句。请参阅文档