C# 将字符串拆分为标记的更直观方法?
C# More intuitive way to split a string into tokens?
我有一个接受字符串的方法,其中包含各种字符,但我只关心下划线“_”和美元符号“$”。我想通过下划线将字符串拆分为标记,因为每一部分 b/w 下划线都包含重要信息。
但是,如果 $ 包含在下划线之间的区域中,则应从下划线的最后一次出现到末尾创建一个标记(忽略最后一部分中的任何下划线)。
例子
输入:Hello_To_The$Great_World
预期标记:你好,To,The$Great_World
问题
我在下面有一个解决方案,但我想知道是否有 cleaner/more 比我下面的方法更直观的方法?
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;
}
}
此方法既不高效也不干净,但它可以让您大致了解如何执行此操作:
- 将字符串拆分为标记
- 查找包含$
的第一个字符串的索引
- Return 一个包含前 n 个标记的新数组,最后一个标记是剩余字符串的连接。
利用 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;
}
这是我的版本(循环是 所以 去年...)
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));
}
编辑:
我应该补充一点,cleaner/more 直觉是非常主观的,正如您从提供的各种答案中发现的那样。从可维护性的角度来看,对您编写的用于解析的方法进行单元测试更为重要!
测试此处发布的各种方法的性能也是一个有趣的练习 - 很快就会发现您的原始版本比使用正则表达式快得多! (尽管在现实生活中,此方法的性能不太可能对您的应用程序产生任何影响!)
您可以通过 _
之前没有 $
来拆分字符串。
为此,您可以使用以下正则表达式:
(?<!$.*)_
示例代码:
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];
我有一个接受字符串的方法,其中包含各种字符,但我只关心下划线“_”和美元符号“$”。我想通过下划线将字符串拆分为标记,因为每一部分 b/w 下划线都包含重要信息。
但是,如果 $ 包含在下划线之间的区域中,则应从下划线的最后一次出现到末尾创建一个标记(忽略最后一部分中的任何下划线)。
例子
输入:Hello_To_The$Great_World
预期标记:你好,To,The$Great_World
问题
我在下面有一个解决方案,但我想知道是否有 cleaner/more 比我下面的方法更直观的方法?
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;
}
}
此方法既不高效也不干净,但它可以让您大致了解如何执行此操作:
- 将字符串拆分为标记
- 查找包含$ 的第一个字符串的索引
- Return 一个包含前 n 个标记的新数组,最后一个标记是剩余字符串的连接。
利用 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;
}
这是我的版本(循环是 所以 去年...)
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));
}
编辑:
我应该补充一点,cleaner/more 直觉是非常主观的,正如您从提供的各种答案中发现的那样。从可维护性的角度来看,对您编写的用于解析的方法进行单元测试更为重要!
测试此处发布的各种方法的性能也是一个有趣的练习 - 很快就会发现您的原始版本比使用正则表达式快得多! (尽管在现实生活中,此方法的性能不太可能对您的应用程序产生任何影响!)
您可以通过 _
之前没有 $
来拆分字符串。
为此,您可以使用以下正则表达式:
(?<!$.*)_
示例代码:
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];