• 简单的字符串命名模板的写法


    简单的字符串命名模板的写法,抄自微软的mvc.

    test[testa] testa='123' test123

    test[[testa]] testa='123' test[testa]

    test [[[testa]]] testa='123' test [123]

    /// copy from Microsoft.AspNetCore.Mvc.ApplicationModels
    /// AttributeRouteModel.cs

    public static string ReplaceTokens(string template, IDictionary<string, string> values)
    {
    var builder = new StringBuilder();
    var state = TemplateParserState.Plaintext;

    int? tokenStart = null;

    // We'll run the loop one extra time with 'null' to detect the end of the string.
    for (var i = 0; i <= template.Length; i++)
    {
    var c = i < template.Length ? (char?)template[i] : null;
    switch (state)
    {
    case TemplateParserState.Plaintext:
    if (c == '[')
    {
    state = TemplateParserState.SeenLeft;
    break;
    }
    else if (c == ']')
    {
    state = TemplateParserState.SeenRight;
    break;
    }
    else if (c == null)
    {
    // We're at the end of the string, nothing left to do.
    break;
    }
    else
    {
    builder.Append(c);
    break;
    }
    case TemplateParserState.SeenLeft:
    if (c == '[')
    {
    // This is an escaped left-bracket
    builder.Append(c);
    state = TemplateParserState.Plaintext;
    break;
    }
    else if (c == ']')
    {
    // This is zero-width parameter - not allowed.
    var message =

    "TokenReplacement_EmptyTokenNotAllowed";
    throw new InvalidOperationException(message);
    }
    else if (c == null)
    {
    // This is a left-bracket at the end of the string.
    var message = "TokenReplacement_UnclosedToken";
    throw new InvalidOperationException(message);
    }
    else
    {
    tokenStart = i;
    state = TemplateParserState.InsideToken;
    break;
    }
    case TemplateParserState.SeenRight:
    if (c == ']')
    {
    // This is an escaped right-bracket
    builder.Append(c);
    state = TemplateParserState.Plaintext;
    break;
    }
    else if (c == null)
    {
    // This is an imbalanced right-bracket at the end of the string.
    var message = "TokenReplacement_ImbalancedSquareBrackets";
    throw new InvalidOperationException(message);
    }
    else
    {
    // This is an imbalanced right-bracket.
    var message = "TokenReplacement_ImbalancedSquareBrackets";
    throw new InvalidOperationException(message);
    }
    case TemplateParserState.InsideToken:
    if (c == '[')
    {
    state = TemplateParserState.InsideToken | TemplateParserState.SeenLeft;
    break;
    }
    else if (c == ']')
    {
    state = TemplateParserState.InsideToken | TemplateParserState.SeenRight;
    break;
    }
    else if (c == null)
    {
    // This is an unclosed replacement token
    var message = "TokenReplacement_UnclosedToken";
    throw new InvalidOperationException(message);
    }
    else
    {
    // This is a just part of the parameter
    break;
    }
    case TemplateParserState.InsideToken | TemplateParserState.SeenLeft:
    if (c == '[')
    {
    // This is an escaped left-bracket
    state = TemplateParserState.InsideToken;
    break;
    }
    else
    {
    // Unescaped left-bracket is not allowed inside a token.
    var message = "TokenReplacement_UnescapedBraceInToken";
    throw new InvalidOperationException(message);
    }
    case TemplateParserState.InsideToken | TemplateParserState.SeenRight:
    if (c == ']')
    {
    // This is an escaped right-bracket
    state = TemplateParserState.InsideToken;
    break;
    }
    else
    {
    // This is the end of a replacement token.
    var token = template
    .Substring(tokenStart.Value, i - tokenStart.Value - 1)
    .Replace("[[", "[")
    .Replace("]]", "]");

    if (!values.TryGetValue(token, out var value))
    {
    // Value not found
    var message = $"TokenReplacement_ReplacementValueNotFound{string.Join(", ", values.Keys.OrderBy(k => k, StringComparer.OrdinalIgnoreCase))}";
    throw new InvalidOperationException(message);
    }

    builder.Append(value);

    if (c == '[')
    {
    state = TemplateParserState.SeenLeft;
    }
    else if (c == ']')
    {
    state = TemplateParserState.SeenRight;
    }
    else if (c == null)
    {
    state = TemplateParserState.Plaintext;
    }
    else
    {
    builder.Append(c);
    state = TemplateParserState.Plaintext;
    }

    tokenStart = null;
    break;
    }
    }
    }

    return builder.ToString();
    }

    [Flags]
    private enum TemplateParserState : uint
    {
    // default state - allow non-special characters to pass through to the
    // buffer.
    Plaintext = 0,

    // We're inside a replacement token, may be combined with other states to detect
    // a possible escaped bracket inside the token.
    InsideToken = 1,

    // We've seen a left brace, need to see the next character to find out if it's escaped
    // or not.
    SeenLeft = 2,

    // We've seen a right brace, need to see the next character to find out if it's escaped
    // or not.
    SeenRight = 4,
    }

  • 相关阅读:
    快速开始Python/WSGI应用程序
    git clone 指定的单个目录或文件夹
    django-1-应用开发基本套路
    raid管理
    Linux下利用script命令录制并回放终端会话
    Mysqldump参数大全
    在crontab中执行脚本重要事项
    IDEA 不能搜索插件解决方案之一
    将页面整体显示为灰色的 CSS
    Linux CentOS7.5静默安装Oracle11gR2
  • 原文地址:https://www.cnblogs.com/forhell/p/11377647.html
Copyright © 2020-2023  润新知