我有一个方法,它接受一个包含各种字符的字符串,但我只关注下划线'_'和美元符号'$'。我希望通过下划线将字符串拆分为令牌,因为下划线包含重要信息。
但是,如果$包含在下划线之间的区域中,那么应该从最后一次下划线到结尾创建一个标记(忽略最后一节中的任何下划线)。
示例
输入:Hello_To_The $ Great_World
预期的代币:你好,To,$ 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;
}
}
答案 0 :(得分:2)
您可以按_
分割字符串,而不是$
。
为此您可以使用以下正则表达式:
(?<!\$.*)_
示例代码:
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];
答案 1 :(得分:1)
此方法效率不高或干净,但它可以让您大致了解如何执行此操作:
利用IEnumerable或者通过for循环而不是所有这些Array.Copy的东西可能更有用......但是你得到了它的要点。
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;
}
答案 2 :(得分:1)
这是我的版本(循环所以去年......)
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));
}
修改:
我应该添加,更清晰/更直观是非常主观的,因为你已经通过提供的各种答案找到了。从可维护性的角度来看,编写解析方法的单元测试更为重要!
测试此处发布的各种方法的性能也是一项有趣的练习 - 很快就会发现原始版本比使用正则表达式要快得多! (虽然在现实生活中,这种方法的性能可能不会对你的应用产生任何影响!)