簡體   English   中英

C#字符串處理一個非分隔字符串以列出

[英]C# String processing a non-delimited string to list

這是有問題的字符串的示例:

[952,M] [782,M] [782] {2[373,M]} [1470] [352] [235] [234] {3[610]}{3[380]} [128] [127]

我已經添加了空格,但實際上並沒有幫助分解。 我要做的是將每個“字段”放在方括號中,並將其添加到字符串列表中。 我可以處理的下一個問題是某些字段也有一個逗號分隔的部分,我可以在事后將其拆分。 真正的問題在於花括號。 例如{2[373,M]}方括號外的數字是方括號的重復。

對於我的一生,我無法找到一種方法可以始終如一地將行拆分為字符串列表。

准代碼如下:

for(i = 0 to string.length)
{
    if string.substring(i,1) = "]"
        int start1 = i
    elseif string.substring(i,1)="["
        int start1 = i
    elseif string.substring(i,1) = "{"
        int start2 = i
    elseif string.substring(i,1) = "}"
        int end2 = i
}

我考慮過使用上面的代碼思想對每個“字段”進行子串化,但是花括號還包含方括號。 任何想法將不勝感激。

如果我對您的理解正確,則希望將方括號括起來的字符分開,當大括號括起來時,將內容重復指定次數。

您可以使用正則表達式提取所需的所有信息,包括確定重復括號所需的次數。

var input = @"[952,M] [782,M] [782] {2[373,M]} 
              [1470] [352] [235] [234] {3[610]}{3[380]} [128] [127]";

var pattern = @"((:?\{(\d+)(.*?)\})|(:?\[.*?\]))";

MatchCollection matches = Regex.Matches(input, pattern);

var ls = new List<string>();

foreach(Match match in matches)
{
    // check if the item has curly brackets
    // The captures groups will be different if there were curly brackets

    // If there are brackets than the 4th capture group 
    // will have the value of the square brackets and it's content
    if( match.Groups[4].Success ) 
    {
        var value = match.Groups[4].Value;

        // The "Count" of the items will 
        // be in the third capture group
        var count = int.Parse(match.Groups[3].Value);

        for(int i=0;i<count;i++)
        {
            ls.Add(value);
        } 

    }
    else
    {
        // otherwise we know that square bracket input 
        // is in the first capture group
        ls.Add(match.Groups[1].Value);
    }
}

這是解決方案的工作提琴: https : //dotnetfiddle.net/4rQsDj

這是輸出:

[952,M]
[782,M]
[782]
[373,M]
[373,M]
[1470]
[352]
[235]
[234]
[610]
[610]
[610]
[380]
[380]
[380]
[128]
[127]

如果您不希望通過將正則表達式模式更改為(:?(:?\\{(\\d+)\\[(.*?)\\]\\})|(:?\\[(.*?)\\]))match.Groups[1].Value match.Groups[6].Value

這是不帶方括號的有效解決方案: https : //dotnetfiddle.net/OQwStf

下面的正則表達式可以處理兩種情況:

(?:\{([^\[]+)){0,1}\[([^\]]+)\]\}{0,1}

對於沒有大括號的情況,第一個匹配為空。 對於第二種情況,第一個匹配項將包含您的重復次數。 在這兩種情況下,第二個匹配項將包含實際數據。 以下鏈接顯示了此工作的演示:

正則表達式演示

但是請注意,您將必須在使用正則表達式的代碼中自行處理重復

雖然您可以使用RegEx,但如果您的需求變得過於復雜,它可能會顯得很短。 因此,下面的代碼顯示了我將采用的一般方法。 有點快速又臟,但是可以滿足您的要求。

此外,我還有一個解析幫助器類該類使該代碼更易於編寫和更強大。

string input = "[952,M] [782,M] [782] {2[373,M]} [1470] [352] [235] [234] {3[610]}{3[380]} [128] [127]";
int pos = 0;

void Main()
{
    while (pos < input.Length)
    {
        SkipWhitespace();
        if (pos < input.Length && input[pos] == '{')
            ParseBrace();
        else if (pos < input.Length && input[pos] == '[')
            ParseBracket();
    }
}

void SkipWhitespace()
{
    while (pos < input.Length && char.IsWhiteSpace(input[pos]))
        pos++;
}

void ParseBrace()
{
    Debug.Assert(pos < input.Length && input[pos] == '{');
    int pos2 = input.IndexOf('[', pos + 1);
    if (pos2 < 0)
        pos2 = input.Length;

    int count = int.Parse(input.Substring(pos + 1, pos2 - pos - 1));
    for (int i = 0; i < count; i++)
    {
        pos = pos2;
        ParseBracket();
    }

    pos2 = input.IndexOf('}', pos2 + 1);
    if (pos2 < 0)
        pos2 = input.Length;

    pos = pos2 + 1;
}

void ParseBracket()
{
    Debug.Assert(pos < input.Length && input[pos] == '[');
    int pos2 = input.IndexOf(']', pos + 1);
    if (pos2 < 0)
        pos2 = input.Length;
    Console.WriteLine(input.Substring(pos + 1, pos2 - pos - 1));
    pos = pos2 + 1;
}

樣本輸出:

952,M
782,M
782
373,M
373,M
1470
352
235
234
610
610
610
380
380
380
128
127
var s = "[952,M] [782,M] [782] {2[373,M]} [1470] [352] [235] [234] {3[610]}{3[380]} [128] [127]";

var s2 = Regex.Replace(s, @"\{(\d+)(\[[^]]+\])\}", m => string.Concat( 
    Enumerable.Repeat(m.Groups[2].Value, int.Parse(m.Groups[1].Value))));

var a = s2.Split("[] ".ToArray(), StringSplitOptions.RemoveEmptyEntries);

// s2 = "[952,M] [782,M] [782] [373,M][373,M] [1470] [352] [235] [234] [610][610][610][380][380][380] [128] [127]"
// a = {"952,M","782,M","782","373,M","373,M","1470","352","235","234","610","610","610","380","380","380","128","127"}

您可以使用正則表達式。

編輯:這解決了逗號和重復的問題:

        var regex3 = new Regex(@"(\B\[([a-zA-Z0-9\,]+)\])|(\{(\d+)\[([a-zA-Z0-9\,]+)\]\})");
        var stringOne = "[952,M] [782,M] [782] {2[373,M]} [1470] [352] [235] [234] {3[610]}{3[380]} [128] [127]";
        var matches = regex.Matches(stringOne);

        var listStrings = new List<string>();

        foreach (Match match in matches)
        {
            var repetitor = 1;
            string value = null;
            if (match.Groups[1].Value == string.Empty)
            {
                repetitor = int.Parse(match.Groups[4].Value);
                value = match.Groups[5].Value;
            }

            else
            {
                value = match.Groups[2].Value;
            }

            var values = value.Split(',');
            for (var i = 0; i < repetitor; i++)
            {
                listStrings.AddRange(values);
            }
        }

暫無
暫無

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

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