c#更直观的将字符串分割成令牌的方法
本文关键字:令牌 方法 分割 直观 字符串 | 更新日期: 2023-09-27 18:07:30
我有一个方法,它接受一个字符串,其中包含各种字符,但我只关心下划线'_'和美元符号'$'。我想通过下划线将字符串分成标记,因为每个下划线都包含重要信息。
但是,如果$包含在下划线之间的区域中,则应该从最后出现的下划线到末尾创建一个令牌(忽略最后一节中的任何下划线)。
输入:Hello_To_The美元Great_World
期望标记:Hello, To, The$Great_World
我下面有一个解决方案,但我想知道是否有一个更干净/更直观的方法来做到这一点比我下面有什么?
var aTokens = new List<string>();
var aPos = 0;
for (var aNum = 0; aNum < item.Length; aNum++)
{
if (aNum == item.Length - 1)
{
aTokens.Add(item.Substring(aPos, item.Length - aPos));
break;
}
if (item[aNum] == '$')
{
aTokens.Add(item.Substring(aPos, item.Length - aPos));
break;
}
if (item[aNum] == '_')
{
aTokens.Add(item.Substring(aPos, aNum - aPos));
aPos = aNum + 1;
}
}
可以通过_
之前没有$
来分割字符串
您可以使用以下regex:
(?<!'$.*)_
示例代码:
string input = "Hello_To_The$Great_World";
string[] output = Regex.Split(input, @"(?<!'$.*)_");
您也可以在没有正则表达式和循环的情况下完成任务,但可以使用2个拆分:
string input = "Hello_To_The$Great_World";
string[] temp = input.Split(new[] { '$' }, 2);
string[] output = temp[0].Split('_');
if (temp.Length > 1)
output[output.Length - 1] = output[output.Length - 1] + "$" + temp[1];
这个方法既不高效也不干净,但它给了您一个如何做到这一点的一般概念:
- 将字符串拆分为token
- 查找包含$ 的第一个字符串的索引
- 返回一个包含前n个标记的新数组,最后一个标记是剩余字符串的连接。
利用IEnumerable或在for循环中做事情可能比使用这个Array更有用。复制的东西……但是你知道要点了。
private string[] SomeMethod(string arg)
{
var strings = arg.Split(new[] { '_' });
var indexedValue = strings.Select((v, i) => new { Value = v, Index = i }).FirstOrDefault(x => x.Value.Contains("$"));
if (indexedValue != null)
{
var count = indexedValue.Index + 1;
string[] final = new string[count];
Array.Copy(strings, 0, final, 0, indexedValue.Index);
final[indexedValue.Index] = String.Join("_", strings, indexedValue.Index, strings.Length - indexedValue.Index);
return final;
}
return strings;
}
这是我的版本(循环是所以去年…)
const char dollar = '$';
const char underscore = '_';
var item = "Hello_To_The$Great_World";
var aTokens = new List<string>();
int dollarIndex = item.IndexOf(dollar);
if (dollarIndex >= 0)
{
int lastUnderscoreIndex = item.LastIndexOf(underscore, dollarIndex);
if (lastUnderscoreIndex >= 0)
{
aTokens.AddRange(item.Substring(0, lastUnderscoreIndex).Split(underscore));
aTokens.Add(item.Substring(lastUnderscoreIndex + 1));
}
else
{
aTokens.Add(item);
}
}
else
{
aTokens.AddRange(item.Split(underscore));
}
编辑:我应该补充一句,更干净/更直观是非常主观的,正如你从提供的各种答案中发现的那样。从可维护性的角度来看,编写用于进行解析的方法进行单元测试要重要得多!
测试这里发布的各种方法的性能也是一个有趣的练习——很快就会发现你的原始版本比使用正则表达式快得多!(尽管在实际情况中,此方法的性能可能不太可能对您的应用程序产生任何影响!)