解析字符串中的标记
Parsing tokens in strings
注意:我使用的是 "token" 这个词,但我不确定它是否是这类东西的正确术语。
我有一个带有标记的字符串,看起来像这样:I'm {name}, blablabla {a:foo} and {a,b : bar}
.
所以每个标记都被 {}
包围并且可以在 :
之前有一些设置(逗号分隔列表)。所以每个标记看起来像 {id}
或 {set,tings:id}
。那里也可能有一些额外的空格:{ set, tings : id }
.
现在我有了提供这些 ID 的对象。因此,例如我有 2 个对象,一个具有 id name == "Jef"
,另一个具有 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",所以我实际上并没有将设置 解析为逗号分隔列表。
看看在 Codeproject
上找到的 FastReplacer
注意:我使用的是 "token" 这个词,但我不确定它是否是这类东西的正确术语。
我有一个带有标记的字符串,看起来像这样:I'm {name}, blablabla {a:foo} and {a,b : bar}
.
所以每个标记都被 {}
包围并且可以在 :
之前有一些设置(逗号分隔列表)。所以每个标记看起来像 {id}
或 {set,tings:id}
。那里也可能有一些额外的空格:{ set, tings : id }
.
现在我有了提供这些 ID 的对象。因此,例如我有 2 个对象,一个具有 id name == "Jef"
,另一个具有 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",所以我实际上并没有将设置 解析为逗号分隔列表。
看看在 Codeproject
上找到的 FastReplacer