0

I have a string in my C# model populated with this string:

"[{\"ta_id\":97497,\"partner_id\":\"229547\",\"partner_url\":\"http://partner.com/deeplink/to/229547\"},{\"ta_id\":97832,\"partner_id\":\"id34234\",\"partner_url\":\"http://partner.com/deeplink/to/id34234\"}]"

Is there a way, using LINQ or RegEx, that I could parse out the partner_id's - so I ended up with a list object with:

229547
id34234

Thanks for your help, Mark

Mark
  • 7,778
  • 24
  • 89
  • 147
  • 7
    That looks like a JSON string, so you could parse it to a class using [Json Serializer](http://msdn.microsoft.com/en-us/library/bb410770(v=vs.110).aspx). [This might help too](http://stackoverflow.com/questions/2859753/what-is-the-simplest-c-sharp-function-to-parse-a-json-string-into-an-object) – musefan Nov 05 '13 at 11:30
  • 1
    You can also take a look at this popular JSON serializer: http://www.nuget.org/packages/Newtonsoft.Json/ – lightbricko Nov 05 '13 at 11:33
  • @musefan indeed, and heres a nice example http://msdn.microsoft.com/en-us/library/bb412179%28v=vs.110%29.aspx – Paul Zahra Nov 05 '13 at 11:33
  • Hi - what class does DataContractJsonSerializer belong in? I'm using Visual Studio, and the usual Ctl + . isn't giving any options. I have installed Newtonsoft.Json from nuget. Thank you, Mark – Mark Nov 05 '13 at 11:48

4 Answers4

2

Assuming your link having partner id always-

   string Name = "[{\"ta_id\":97497,\"partner_id\":\"229547\",\"partner_url\":\"http://partner.com/deeplink/to/229547\"},{\"ta_id\":97832,\"partner_id\":\"id34234\",\"partner_url\":\"http://partner.com/deeplink/to/id34234\"}]";

        string[] splittedString = Regex.Split(Name, "}");
        List<string> allIds = new List<string>();
        foreach (var i in splittedString)
        { 
            var ids =Regex.Split(i, "/");
            string id = ids[ids.Length - 1];
            allIds.Add(id);
        }
monu
  • 370
  • 1
  • 10
2

I have never used any JSON parser but if it comes to Regex you could try something like this:

private static void regexString()
{
    string myString = "[{\"ta_id\":97497,\"partner_id\":\"229547\",\"partner_url\":\"http://partner.com/deeplink/to/229547\"},{\"ta_id\":97832,\"partner_id\":\"id34234\",\"partner_url\":\"http://partner.com/deeplink/to/id34234\"}]";

    string[] stringList = Regex.Split(myString, "},{");

    for (int i=0; i<stringList.Length ;i++)
    {
        stringList[i] = Regex.Split(Regex.Split(stringList[i], "partner_id\\\":\\\"")[1], "\\\",\\\"partner_url\\\"")[0];
    }
}

Also there is a nice website to help you with creating your own regex patterns in the future, check it out:

gskinner.com

And a nice and short tutorial:

www.codeproject.com

Tafari
  • 2,639
  • 4
  • 20
  • 28
2

If that is the general format of the string then this regex should work

(?i)(?<=(partner_id).{5})\w+

Test here

This from your string will get

229547 and id34234

(?i) = Case insesitivity

(?<=(partner_id).{5}) = postive lookbehind for parter_id then any 5 characters which in this case will be \":\"

\w+ = Any alphanumeric characters one or more times

Hope this helped

Srb1313711
  • 2,017
  • 5
  • 24
  • 35
  • @ +1 for optimalization ,time for me to learn `lookbehind` more... Anyway could you explain (?i) for me as I don't really get it. – Tafari Nov 05 '13 at 12:55
  • Your `{5}` should be `{3}`. – Kendall Frey Nov 05 '13 at 13:11
  • 1
    Yeah sure (?i) basically if you have say the string 'tafari', to match this you might use [a-z]+ but this only matches lower case 'tafari' what if you were to have 'TafARI' in some cases or 'TAFAri' etc. Yes you could use [a-zA-Z]+ but my preffered way is to use (?i) which will match stings matched by your regex but they can be upper or lower case or a mixture of both. So to match any cased 'Tafari' i would use (?i)[a-z]+. Does this help? – Srb1313711 Nov 05 '13 at 14:21
  • @Srb1313711 so basically it would be the same as **(\w?)** ? – Tafari Nov 05 '13 at 16:34
  • 1
    Yes and no \w will get both upper and lower case but will also get numbers, if your just searching for strings I would advise using [a-z] to avoid matching anything unwanted. The same with numbers I would use [0-9] instead of \d as \d matches all Unicode characters not just 0-9. Also by specifying (?i) at the beginning you don't have to keep repeating [a-zA-Z] unless you only want case insensitivity in certain places. – Srb1313711 Nov 05 '13 at 17:08
  • @Srb1313711 well obviously I understand it better now, so thank you : ) – Tafari Nov 05 '13 at 20:58
0

Since this is JSON, you probably shouldn't bother trying to get a regex working. Instead, you can parse the JSON and then use LINQ.

using System.Web.Script.Serialization; // (in System.Web.Extensions.dll)

...

string s = "[{\"ta_id\":97497,\"partner_id\":\"229547\",\"partner_url\":\"http://partner.com/deeplink/to/229547\"},{\"ta_id\":97832,\"partner_id\":\"id34234\",\"partner_url\":\"http://partner.com/deeplink/to/id34234\"}]";
JavaScriptSerializer j = new JavaScriptSerializer();
object[] objects = (object[])j.DeserializeObject(s);
string[] ids = objects.Cast<Dictionary<string, object>>()
                      .Select(dict => (string)dict["partner_id"])
                      .ToArray();

It's a little messy to deserialize it to an object, because you don't have any type information. If you're not afraid of making a small class to deserialize into, you can do something like this:

class Foo
{
    public string partner_id
    {
        get;
        set;
    }
}

...

JavaScriptSerializer j = new JavaScriptSerializer();
string[] ids = j.Deserialize<Foo[]>(s).Select(x => x.partner_id).ToArray();

Note that there are other options for deserializing JSON. I simply chose the most general-purpose one that's built in.

Kendall Frey
  • 43,130
  • 20
  • 110
  • 148