【问题标题】:Parsing tokens in strings解析字符串中的标记
【发布时间】:2016-01-19 15:11:35
【问题描述】:

注意:我使用的是“token”这个词,但我不确定它是否适合这种东西。

我有一个带有标记的字符串,看起来像这样:I'm {name}, blablabla {a:foo} and {a,b : bar}

所以每个标记都被{} 包围,并且在: 之前可以有一些设置(逗号分隔列表)。所以每个令牌看起来像{id}{set,tings:id}。那里可能还有一些额外的空白:{ set, tings : id }

现在我有了提供这些 id 的对象。例如,我有 2 个对象,一个 ID 为 name == "Jef",另一个 ID 为 name == "An"。但实际上我有很多很多对象。这些对象有一个string getValue(string id) 方法。 id 的值始终是字符串。而且我也有一些方法对应这些设置。因此,例如,如果lower 是其中一种设置,则最终结果将全部为小写字母。最后,我需要用 id 后面的值和要应用的所需设置来填充所有标记。

我只有几个这样的字符串,但它们需要由许多不同的对象填充。所以我想知道解析这个的好方法是什么?通过某种预处理,字符串应该只解释一次,然后可以非常快速地多次填充。

目前我正在使用正则表达式的组合来获取{} 之间的内容,然后使用完全自定义的代码对其进行解析。每次我想用值填充它时,我也只是再次解析字符串,但这看起来有点难看。因此,如果有更好的方法来做到这一点,甚至可能是一些(内置)库,那就太好了。

注意:我使用{a,b:id} 方案是因为我喜欢它的外观,但如果有更好的方法在我的字符串中表示这些标记,我可以接受。但是,有些字符串是 url,所以我不能使用 / 或其他东西作为分隔符。


我当前的代码:

public class Token
{
    private string _id;
    public string ID { get { return _id; } }

    private string _settings;

    public Token(string token)
    {
        if (token.Contains(":"))
        {
            int separator = token.IndexOf(":");
            _settings = token.Substring(0, separator).Trim();
            _id = token.Substring(separator+1).Trim();
        }
        else
        {
            _id = token.Trim();
        }
    }

    public string GetValueFrom(CardInfo cardInfo)
    {
        string value = cardInfo.GetById(_id).Value; // GetById returns a wrapper for string for some reason, but .Value always gives a string.
        if (_settings != null && _settings.Contains("e"))
        {
            value = WWW.EscapeURL(value); //WWW from Unity
        }

        return value;
    }
}



private static readonly Regex TOKEN_REGEX = new Regex(@"{(.+)}");

public static IEnumerable<Token> GetAllTokensFrom(string text)
{
    return TOKEN_REGEX.Matches(text).Cast<Match>().Select(m => new Token(m.Groups[1].Value));
}

public static string FillAllTokensIn(string text, CardInfo info)
{
    return TOKEN_REGEX.Replace(text, m => TranslateToken(m.Groups[1].Value, info));
}

private static string TranslateToken(string value, CardInfo card)
{
    Token token = new Token(value);
    return token.GetValueFrom(card);
}

注意:我目前只有设置“e”,所以我实际上并没有将设置解析为逗号分隔的列表。

【问题讨论】:

  • 你的问题有点模糊和广泛。您能否提供更具体的示例并分享您拥有的一些代码。
  • @MattBurland 我添加了我当前的代码。它很快就组装好了,目前还远远不够。
  • ...but this is a little slow - 请定义slow。它有多慢,你期望什么?
  • 好吧,我没有做过任何真正的性能测试,所以实际上说它很慢是错误的。但是,每次我想填充或获取令牌时,代码都必须在字符串上匹配/替换为正则表达式,这确实感觉不对。似乎应该有一个更好的方法。我已经更新了我的问题,将其重新表述为我的真正问题。

标签: c# string token


【解决方案1】:

看看 Codeproject 上的 FastReplacer

【讨论】:

    猜你喜欢
    • 2023-03-05
    • 1970-01-01
    • 2015-06-26
    • 2012-05-16
    • 1970-01-01
    • 2021-10-01
    • 2017-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多