簡體   English   中英

C#將字符串拆分為令牌的更直觀的方法?

[英]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];

此方法效率不高或不干凈,但可以使您大致了解如何執行此操作:

  1. 將字符串拆分為令牌
  2. 查找第一個包含$的字符串的索引
  3. 返回一個帶有前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));
}

編輯:

我應該補充說,更清潔/更直觀是非常主觀的,正如您從提供的答案中發現的那樣。 從可維護性的角度來看,編寫用於解析的方法進行單元測試更為重要!

測試此處發布的各種方法的性能也是一個有趣的練習-很明顯,您的原始版本比使用正則表達式要快得多! (盡管在現實生活中,此方法的性能可能不太可能對您的應用程序產生任何影響!)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM