user2424146
user2424146

Reputation:

Splitting data with Regex (Regular Expressions)

I would need some help with matching data in this example string:

 req:{REQUESTER_NAME},key:{abc},act:{UPDATE},sku:{ABC123,DEF-123},qty:{10,5}

Essentially, every parameter is separated by "," but it is also included within {} and I need some help with regex as I am not that good with it.

Desired Output:

req = "REQUESTER_NAME"
key = "abc"
act = "UPDATE"
sku[0] = "ABC123"
sku[1] = "DEF-123"
qty[0] = 10
qty[1] = 5

Upvotes: 1

Views: 774

Answers (5)

th1rdey3
th1rdey3

Reputation: 4378

First, use Regex.Matches to get the parameters inside { and }.

string str = "req:{REQUESTER_NAME},key:{abc},act:{UPDATE},sku:{ABC123,DEF-123},qty:{10,5}";
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);

output

REQUESTER_NAME
abc
UPDATE
ABC123,DEF-123
10,5

then use Regex.Split to get the parameter names

string[] arr1 = Regex.Split(str,@"\{.+?\}")
                         .Select(x => x.Trim(new char[]{',',':',' '}))
                         .Where(x => !string.IsNullOrEmpty(x)) //need this to get rid of empty strings
                         .ToArray();
foreach (string s in arr1)
    Console.WriteLine(s);

output

req
key
act
sku
qty

Now you can easily traverse through the parameters. something like this

for(int i=0; i<arr.Length; i++)
{
    if(arr1[i] == "req")
        //arr[i] contains req parameters
    else if(arr1[i] == "sku")
        //arr[i] contains sku parameters
        //use string.Split(',') to get all the sku paramters and process them
}

Upvotes: 1

Gun
Gun

Reputation: 1411

The below sample may helps to solve your problem. But here lot of string manipulations are there.

        string input = "req:{REQUESTER_NAME},key:{abc},act:{UPDATE},sku:{ABC123,DEF-123},qty:{10,5}";

        Console.WriteLine(input);

        string[] words = input.Split(new string[] { "}," }, StringSplitOptions.RemoveEmptyEntries);

        foreach (string item in words)
        {
            if (item.Contains(':'))
            {
                string modifiedString = item.Replace(",", "," + item.Substring(0, item.IndexOf(':')) + ":");

                string[] wordsColl = modifiedString.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                foreach (string item1 in wordsColl)
                {
                    string finalString = item1.Replace("{", "");
                    finalString = finalString.Replace("}", "");
                    Console.WriteLine(finalString);
                }
            }
        }

Upvotes: 2

dljve
dljve

Reputation: 545

Kishore's solution is perfect, but here is another solution that works with regex:

Dim input As String = "req:{REQUESTER_NAME},key:{abc},act:{UPDATE},sku:{ABC123,DEF-123},qty:{10,5}"
Dim Array = Regex.Split(input, ":{|}|,")

This does essentially the same, it uses regex to split on :{, } and ,. The solution might be a bit shorter though. The values will be put into the array like this:

"req", "REQUESTER_NAME","", ... , "qty", "10", "5", ""

Notice after the parameter and its value(s) there will be an empty string in the array. When looping over the array you can use this to let the program know when a new parameter starts. Then you can create a new array/data structure to store its values.

Upvotes: 0

NYCdotNet
NYCdotNet

Reputation: 4647

Kishore's answer is correct. This extension method may help implement that suggestion:

<Extension()>
Function WideSplit(InputString As String, SplitToken As String) As String()
    Dim aryReturn As String()
    Dim intIndex As Integer = InputString.IndexOf(SplitToken)
    If intIndex = -1 Then
        aryReturn = {InputString}
    Else
        ReDim aryReturn(1)
        aryReturn(0) = InputString.Substring(0, intIndex)
        aryReturn(1) = InputString.Substring(intIndex + SplitToken.Length)
    End If
    Return aryReturn
End Function

If you import System.Runtime.CompilerServices, you can use it like this:

Dim stringToParse As String = "req:{REQUESTER_NAME},key:{abc},act:{UPDATE},sku:{ABC123,DEF-123},qty:{10,5}"
Dim strTemp As String
Dim aryTemp As String()
strTemp = stringToParse.WideSplit("req:{")(1)
aryTemp = strTemp.WideSplit("},key:{")
req = aryTemp(0)
aryTemp = aryTemp(1).WideSplit("},act:{")
key = aryTemp(0)
'etc...

You may be able do this more memory efficiently, though, as this method creates a number of temporary string allocations.

Upvotes: 0

Kishore Venkateshan
Kishore Venkateshan

Reputation: 31

I would suggest you do the following

  1. Use String Split with ',' character as the separator (eg output req:{REQUESTER_NAME})
  2. With each pair of data, do String Split with ';' character as the separator (eg output "req", "{REQUESTER_NAME}")
  3. Do a String Replace for characters '{' and '}' with "" (eg output REQUESTER_NAME)
  4. Do a String Split again with ',' character as separator (eg output "ABC123", "DEF-123")

That should parse it for you perfectly. You can store the results into your data structure as the results come in. (Eg. You can store the name at step 2 whereas the value for some might be available at Step 3 and for others at Step 4)

Hope That Helped

Note: - If you don't know string split - http://www.dotnetperls.com/split-vbnet - If you don't know string replace - http://www.dotnetperls.com/replace-vbnet

Upvotes: 2

Related Questions