2

I am trying to use regex to split the string into 2 arrays to turn out like this.

String str1 = "First Second [insideFirst] Third Forth [insideSecond] Fifth";

How do I split str1 to break off into 2 arrays that look like this:

ary1 = ['First Second','Third Forth','Fifth'];
ary2 = ['insideFirst','insideSecond'];
3
  • I have edited your title. Please see, "Should questions include “tags” in their titles?", where the consensus is "no, they should not". Commented Oct 22, 2013 at 4:23
  • Do you care about nested brackets? Commented Oct 22, 2013 at 4:27
  • Show your regular Expression which you try Commented Oct 22, 2013 at 4:50

5 Answers 5

2

here is my solution

string str = "First Second [insideFirst] Third Forth [insideSecond] Fifth";
MatchCollection matches = Regex.Matches(str,@"\[.*?\]");
string[] arr = matches.Cast<Match>()
                      .Select(m => m.Groups[0].Value.Trim(new char[]{'[',']'}))
                      .ToArray();
foreach (string s in arr)
{
    Console.WriteLine(s);
}

string[] arr1 = Regex.Split(str,@"\[.*?\]")
                     .Select(x => x.Trim())
                     .ToArray();
foreach (string s in arr1)
{
    Console.WriteLine(s);
}

Output

insideFirst
insideSecond
First Second
Third Forth
Fifth
Sign up to request clarification or add additional context in comments.

4 Comments

This is close, only if you are literally only splitting by square brackets. But it seems obvious to me that the OP was using an Example for this question, not a literal string he wishes to split. In place of the Square-Bracketed example, he may very well be splitting by some other, more complex, pattern.
The question literally say square bracket. If OP wanted something else he could have said so in his question. Also OP accepted this as the correct answer. I think it's best not to make own assumptions.
Actually, it literally does NOT say "square bracket" anywhere in the OP Question. Your answer is great, and useable. But we (should) all understand that square brackets are the universal symbol for Some-Variable-Parameter. E.G.: Suamere [MiddleName] Scalar. My middle name is not [MiddleName], and he certainly was not splitting by [insideFirst]. Even if he MEANT to say square-bracketted-text, he didn't, and I don't think he did. For all we know, he took your answer's c# code, and altered the Regex Patterns in it. He doesn't say. So my point is: The question should be answered as-asked.
in the question he said "brakets []". He followed the word "brackets" with two third bracket symbol and I think it portrays OPs intention to split on those two characters. Hence I said the question literally say square brackets.
0

Plz Try below code. Its working fine for me.

  String str1 = "First Second [insideFirst] Third Forth [insideSecond] Fifth";
    var output = String.Join(";", Regex.Matches(str1, @"\[(.+?)\]")
                                .Cast<Match>()
                                .Select(m => m.Groups[1].Value));

    string[] strInsideBreacket = output.Split(';');


    for (int i = 0; i < strInsideBreacket.Count(); i++)
    {
        str1 = str1.Replace("[", ";");
        str1 = str1.Replace("]", "");
        str1 = str1.Replace(strInsideBreacket[i], "");
    }

    string[] strRemaining = str1.Split(';');

Plz look at below screen shot of output while debugging code:

enter image description here

enter image description here

Here, strInsideBreacket is array of breacket value like insideFirst andinsideSecond and strRemaining is array of First Second,Third Forth and Fifth

Thanks

1 Comment

This isn't good because the implementation knows about the pattern. E.G.: If you were to create a function with your solution named SplitByPattern, which returns a collection of the split results, plus a collection of the resulting regex delimiters, your function would only work if the pattern were EXACTLY the Square-Bracket. However, it is obvious by the Test-Data the OP uses that he isn't going to LITERALLY be splitting by square brackets. So your function would fail.
0

Try this solution,

 String str1 = "First Second [insideFirst] Third Forth [insideSecond] Fifth";
 var allWords = str1.Split(new char[] { '[', ']' }, StringSplitOptions.RemoveEmptyEntries);
 var result = allWords.GroupBy(x => x.Contains("inside")).ToArray();

The idea is that, first get all words and then the group it.

1 Comment

In general, finding a Non-Regex solution is always great. But the OP was asking a generic question. He is only using Square Brackets as the universally-understood text to mean optional or example text. If the pattern he wished to split by didn't have obvious concrete characters, e.g.: \d+\w{2,3}, then this doesn't work. You're coming from a good place, but it doesn't help answer this particular question.
0

It seems to me that "user2828970" asked a question with an example, not with literal text he wanted to parse. In my mind, he could very well have asked this question:

I am trying to use regex to split a string like so.

var exampleSentence = "I had 185 birds but 20 of them flew away";
var regexSplit = Regex.Split(exampleSentence, @"\d+");

The result of regexSplit is: I had, birds but, of them flew away.

However, I also want to know the value which resulted in the second string splitting away from its preceding text, and the value which resulted in the third string splitting away from its preceding text. i.e.: I want to know about 185 and 20.

The string could be anything, and the pattern to split by could be anything. The answer should not have hard-coded values.

Well, this simple function will perform that task. The code can be optimized to compile the regex, or re-organized to return multiple collections or different objects. But this is (nearly) the way I use it in production code.

public static List<Tuple<string, string>> RegexSplitDetail(this string text, string pattern)
{
    var splitAreas = new List<Tuple<string, string>>();

    var regexResult = Regex.Matches(text, pattern);
    var regexSplit = Regex.Split(text, pattern);

    for (var i = 0; i < regexSplit.Length; i++)
        splitAreas.Add(new Tuple<string, string>(i == 0 ? null : regexResult[i - 1].Value, regexSplit[i]));

    return splitAreas;
}

...
var result = exampleSentence.RegexSplitDetail(@"\d+");

This would return a single collection which looks like this:

{ null, "I had "}, // First value, had no value splitting it from a predecessor
{"185", " birds but "}, // Second value, split from the preceding string by "185"
{ "20", " of them flew away"} // Third value, split from the preceding string by "20"

Comments

0

Being that this is a .NET Question and, apart from my more favoured approach in my other answer, you can also capture the Split Value another VERY Simple way. You just then need to create a function to utilize the results as you see fit.

var exampleSentence = "I had 185 birds but 20 of them flew away";
var regexSplit = Regex.Split(exampleSentence, @"(\d+)");

The result of regexSplit is: I had, 185, birds but, 20, of them flew away. As you can see, the split values exist within the split results.

Note the subtle difference compared to my other answer. In this regex split, I used a Capture Group around the entire pattern (\d+) You can't do that!!!?.. can you?

Using a Capture Group in a Split will force all capture groups of the Split Value between the Split Result Capture Groups. This can get messy, so I don't suggest doing it. It also forces somebody using your function(s) to know that they have to wrap their regexes in a capture group.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.