[英]C# More intuitive way to split a string into tokens?
我有一個方法,它接受一個包含各種字符的字符串,但是我只關心下划線'_'和美元符號'$'。 我想通過下划線將字符串拆分為標記,因為每個下划線包含重要信息。
但是,如果在下划線之間的區域中包含$,則應從上次出現的下划線到末尾創建一個令牌(忽略最后一節中的任何下划線)。
例
輸入: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;
}
}
您可以用_
分隔字符串,而在它們之前沒有$
。
為此,您可以使用以下正則表達式:
(?<!\$.*)_
樣例代碼:
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];
此方法效率不高或不干凈,但可以使您大致了解如何執行此操作:
利用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));
}
編輯:
我應該補充說,更清潔/更直觀是非常主觀的,正如您從提供的答案中發現的那樣。 從可維護性的角度來看,編寫用於解析的方法進行單元測試更為重要!
測試此處發布的各種方法的性能也是一個有趣的練習-很明顯,您的原始版本比使用正則表達式要快得多! (盡管在現實生活中,此方法的性能可能不太可能對您的應用程序產生任何影響!)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.