Blanco DDP
Blanco DDP

Reputation: 33

how to deal with string.split by position

I'd like to ask one question about String.Split

For example:

char[] semicolon=new [] {';'};
char[] bracket=new [] {'[',']'};
string str="AND[Firstpart;Sndpart]";

I can split str by bracket and then split by semicolon. Finally,I get the Firstpart and Sndpart in the bracket.

But If str="AND[AND[Firstpart;Sndpart];sndpart]; How can I get AND[Firpart;Sndpart] and sndpart?

Is there a way to tell c# to split by second semicolon?

Thanks for your help

Upvotes: 2

Views: 1262

Answers (3)

w.b
w.b

Reputation: 11238

You can use Regex.Split, which is a more flexible form of String.Split:

string str = "AND[AND[Firstpart;Sndpart];sndpart]";

string[] arr = Regex.Split(str, @"(.*?;.*?;)");


foreach (var s in arr)
    Console.WriteLine("'{0}'", s);

// output: ''
//         'AND[AND[Firstpart;Sndpart];'
//         'sndpart]'

Regex.Split splits not by chars, but by a string matching a regex expression, so it comes down to constructing a regex pattern meeting particular requirements. Splitting by a second semicolon is in practice splitting by a string that ends in a semicolon and that contains another semicolon before, so the matching pattern by which you split the input string could be for example: (.*?;.*?;).

The returned array has three elements instead of two because the splitting regex matches the beginning of the input string, in this case the empty string is returned as the first element.

You can read more on Regex.Split on msdn.

Upvotes: 0

M.kazem Akhgary
M.kazem Akhgary

Reputation: 19179

One way is to hide characters inside bracket with a character that is not used in any of your strings.

Method HideSplit: This method will change separator characters inside brackets with fake ones. Then it will perform split and will give back the result with original characters.

This method maybe an overkill if you want to do this many times. but you should be able to optimize it easily if you got the idea.

    private static void Main()
    {
        char[] semicolon = new[] { ';' };
        char[] bracket = new[] { '[', ']' };
        string str = "AND[AND[Firstpart;Sndpart];sndpart]";

        string[] splitbyBracket = HideSplit(str, bracket);
    }

    private static string[] HideSplit(string str,char[] separator)
    {
        int counter = 0; // When counter is more than 0 it means we are inside brackets
        StringBuilder result = new StringBuilder(); // To build up string as result

        foreach (char ch in str)
        {
            if(ch == ']') counter--;

            if (counter > 0) // if we are inside brackets perform hide
            {
                if (ch == '[') result.Append('\uFFF0'); // add '\uFFF0' instead of '['
                else if (ch == ']') result.Append('\uFFF1');
                else if (ch == ';') result.Append('\uFFF2');
                else result.Append(ch);
            }
            else result.Append(ch);

            if (ch == '[') counter++;
        }


        string[] split = result.ToString().Split(separator); // Perform split. (characters are hidden now)

        return split.Select(x => x
            .Replace('\uFFF0', '[')
            .Replace('\uFFF1', ']')
            .Replace('\uFFF2', ';')).ToArray(); // unhide characters and give back result.
                                               // dont forget: using System.Linq;
    }

Some examples :

string[] a1 = HideSplit("AND[AND[Firstpart;Sndpart];sndpart]", bracket);
// Will give you this array { AND , AND[Firstpart;Sndpart];sndpart }

string[] a2 = HideSplit("AND[Firstpart;Sndpart];sndpart", semicolon);
// Will give you this array { AND[Firstpart;Sndpart] , sndpart }

string[] a3 = HideSplit("AND[Firstpart;Sndpart]", bracket);
// Will give you this array { AND , Firstpart;Sndpart }

string[] a4 = HideSplit("Firstpart;Sndpart", semicolon);
// Will give you this array { Firstpart , Sndpart }

And you can continue splitting this way.

Upvotes: 1

Amit
Amit

Reputation: 46351

Is there a way to tell c# to split by second semicolon?

There is no direct way to do that, but if that is precisely what you want, it's not hard to achieve:

string str="AND[AND[Firstpart;Sndpart];sndpart];
string[] tSplits = str.Split(';', 3);
string[] splits = { tSplits[0] + ";" + tSplits[1], tSplits[2] };

You could achieve the same result using a combination of IndexOf() and Substring(), however that is most likely not what you'll end up using as it's too specific and not very helpful for various inputs.

For your case, you need something that understands context.

In real-world complex cases you'd probably use a lexer / parser, but that seems like an overkill here.

Your best effort would probably be to use a loop, walk through all characters while counting +/- square brackets and spliting when you find a semicolon & the count is 1.

Upvotes: 0

Related Questions