LINQ or REGEX to extract certain text from a string - c#

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

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

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);
}

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

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.

Related

Insert comma into string where two brackets are touching (C#)

I'm trying to write a JSON file in C#, and I have a problem where I want to seperate each object with a comma (',') for it to be valid JSON, however I can't figure out how to do this. I've searched if there is a way you can search for a specific pattern in a string (in my case it would be '}{') and a regular expression might work, but I don't know how to create one.
The final result should look like
'},{'
instead of
'}{'.
Here is my code so far:
private void loopThroughArray()
{
string json = "";
for (int i = 0; i < array.Count; i++)
{
MyObject t = array[i];
json += new JavaScriptSerializer().Serialize(t);
//this writes the json to the file but without comma seperator
}
System.IO.File.WriteAllText(#"<MyFilepath>\json.txt", "{\"json\":[" + json + "]}");
//this writes the json to a file that and is in a json array called 'json'
}
I looked at different ways of serialising JSON as per #Measuring 's suggestion and discovered that this was the easiest method in my opinion:
json = JsonConvert.SerializeObject(MyObject);
Works perfectly, thanks #Measuring!
I agree with #Measuring it seems like an over complication to write your own when there are tools which can be used as identified in this answer.
Nonetheless you could do the following...
string json = "";
for (int i = 0; i < array.Count; i++){
MyObject t = array[i];
json += new JavaScriptSerializer().Serialize(t);
}
string pattern = "\}{\";
string replacement = "},{";
Regex rgx = new Regex(pattern);
string result = rgx.Replace(json, replacement);
What you are trying to do can be solved by string.Join and a bit of Linq
var serializer = new JavaScriptSerializer();
var json = string.Join( ",", array.Select( e => serializer.Serialize(e) );
Looks like this:
json += new JavaScriptSerializer().Serialize(t);
Is creating a {json object}. Your solution might be as easy as appending a , after like:
json += new JavaScriptSerializer().Serialize(t) + ",";
Edit (responding on your comment):
You can easily skip the last loop with an inner check.
json += new JavaScriptSerializer().Serialize(t);
if (i < array.Count - 1) json += ",";
Alternatively you could cut the for-loop 1 item short and add the last item after the loop.
It's far more efficient to use a StringBuilder than += and you should avoid creating reusable objects within loops.
Keeping as close to your code as possible, you could try:
private void loopThroughArray()
{
var serializer = new JavaScriptSerializer();
var json = new System.Text.StringBuilder();
for (int i = 0; i < array.Count; i++)
{
MyObject t = array[i];
json.Append(serializer.Serialize(t));
if (i < array.Count)
json.Append(",");
}
System.IO.File.WriteAllText(#"<MyFilepath>\json.txt", "{\"json\":[" + json.ToString() + "]}");
}
But it may be simpler to try:
private void loopThroughArray()
{
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(array);
System.IO.File.WriteAllText(#"<MyFilepath>\json.txt", "{\"json\":" + json.ToString() + "}");
}
But, if I were doing it I'd use Json.Net's JsonConvert on an anonymous type:
System.IO.File.WriteAllText(
#"<MyFilepath>\json.txt",
JsonConvert.SerializeObject(new {
json = array
}));
You can get Json.Net from nuget.
JsonNet is indeed easier to use, but in your case it feels like
JavaScriptSerializer works fine. Presumably you expect "{json:[...]}" as result - serializing new {json = array} instead of just array will produce that output:
var finalJson = new JavaScriptSerializer().Serialize(new {json = array});
Side note: please avoid manual string manipulation when constructing JSON or XML -it is not worth the effort and result in most cases is somewhat wrong.
Hi Kevin would it not be possible to replace the string using regex expressions,
/}{/g
and replace with
},{

How do I split a list of array?

Here is the list array:
{"things":{"1":"1_4","3":"3_13","4":"4_18","5":"5_25","6":"6_28","7":"7_32"}}
here is the code:
var t = things;
string aa = t[0].ToString();
How do I split the above array in , separator and _ .
from the above array i want only 1_4,3_13...this column and save in two different var.
when I am using
string[] ss = aa.Split(new char[] { ',', '|', }, System.StringSplitOptions.RemoveEmptyEntries);
the problem is that in first list {"things":{"1":"1_4".
comes
so how to remove {"things"??
You should not parse JSON yourself. Do not reinvent the wheel.
You should define a class
public class MyClass
{
[JsonProperty("things")]
public Dictionary<int, string> Things { get; set; }
}
Then deserialize your string into an instance of MyClass
var rawData = "{\"things\":{\"1\":\"1_4\",\"3\":\"3_13\",\"4\":\"4_18\",\"5\":\"5_25\",\"6\":\"6_28\",\"7\":\"7_32\"}}";
var data = JsonConvert.DeserializeObject<MyClass>(rawData);
Then you can use data
Console.WriteLine(data.Things[1]);
You should add Newtonsoft.Json Nuget package to your project and add using Newtonsoft.Json namespace to your code file.
Instead of string manipulation, you should use JSON library like Json.Net. Simply, because you are working with string in JSON format and it will be easier to work with that information if you deserialize it into proper object or JObject.
Example with JObject:
string json = #"{""things"":{""1"":""1_4"",""3"":""3_13"",""4"":""4_18"",""5"":""5_25"",""6"":""6_28"",""7"":""7_32""}}";
var jObj = Newtonsoft.Json.Linq.JObject.Parse(json);
var prop1 = jObj.GetValue("things").GetPropertyValue("1").ConvertTo<string>();
var prop4 = jObj.GetValue("things").GetPropertyValue("4").ConvertTo<string>();
Note: You can create classes which will represent your JSON structure, if you want to have strongly typed object structure.
You should first split by { then discard the first and after that you are left with:
"1":"1_4","3":"3_13","4":"4_18","5":"5_25","6":"6_28","7":"7_32"}}
Now you split with , and get
"1":"1_4"
"3":"3_13" and so on.
Then you split each with : and take the second one.
Only remember that the last one is "7_32"}} which you should remove the trailing }}
Like this:
var elems = aa.Split(new[] { '{' })[1].Split(new[] { ',' });
var res = elems.Select(obj => obj.Trim("}".ToCharArray()).Split(new[] { ':' }));
Hope this is what you want :)

How to convert a string containing an array into a list<ushort> ?

For example there is a
string str = "[2,3,4,5]"
How to convert this array of type string into a list where I can get each element in the list of type ushort?
The string gets the value "[2,3,4,5]" from ruby script.
Using linq you could do it like
var numbers = str.Where(y=>Char.IsDigit(y)).Select(p=>UInt16.Parse(p.ToString())).ToArray();
It's actually quite simple. All you need to do is write a method that parses the string and splits it up. Here is an basic example with NO error checking or optimizations. The naming convention is purely for your understanding purposes.
List <ushort> ConvertToUShortList (string arrayText)
{
var result = new List<ushort> ();
var bracketsRemoved = arrayText.Replace ("[", "").Replace ("]", "");
var numbersSplit = bracketsRemoved.Split ( new string[] {","}, System.StringSplitOptions.None);
foreach (var number in numbersSplit)
{
result.Add (ushort.Parse (number));
}
return result;
}
I shouldn't need to explain anything in this method due to the names I have given things. If you don't understand anything, let me know and I'll clarify it for you.
Another method (more checks):
class Program
{
static void Main(string[] args)
{
var str = "[1,2,3,4,5,6,7,8,9]";
var x = FromRubyArray(str);
Console.WriteLine(str);
Console.WriteLine(string.Join("-", x));
Console.ReadLine();
}
public static List<ushort> FromRubyArray(string stra)
{
if (string.IsNullOrWhiteSpace(stra)) return new List<ushort>();
stra = stra.Trim();
stra = stra.Trim('[', ']');
return stra
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => Convert.ToUInt16(s))
.ToList();
}
}
Since this string is using a "Json-like" format, you can use this code:
JavaScriptSerializer serializer = new JavaScriptSerializer();
var array = serializer.Deserialize<ushort[]>("[2,3,4,5]");
You just need to reference the System.Web.Extensions assembly
Another elegant way using Newtonsoft's Json.net (http://www.newtonsoft.com/json)
var ushortArray = JsonConvert.DeserializeObject<List<ushort>>(myString);
You could do something like
List<ushort> myUshorts = new List<ushort>("[200,3,4,5]".Trim('[', ']').Split(',').Select(ushort.Parse));
if you know that's exactly how the output will be.

Convert String Into Dynamic Object

Is there a straightforward way of converting:
string str = "a=1,b=2,c=3";
into:
dynamic d = new { a = 1, b = 2, c = 3 };
I think I could probably write a function that splits the string and loops the results to create the dynamic object. I was just wondering if there was a more elegant way of doing this.
I think if you convert the "=" into ":" and wrap everything with curly brackets you'll get a valid JSON string.
You can then use JSON.NET to deserialize it into a dynamic object:
dynamic d = JsonConvert.DeserializeObject<dynamic>(jsonString);
You'll get what you want.
You may use Microsoft Roslyn (here's the all-in-one NuGet package):
class Program
{
static void Main(string[] args)
{
string str = "a=1,b=2,c=3,d=\"4=four\"";
string script = String.Format("new {{ {0} }}",str);
var engine = new ScriptEngine();
dynamic d = engine.CreateSession().Execute(script);
}
}
And if you want to add even more complex types:
string str = "a=1,b=2,c=3,d=\"4=four\",e=Guid.NewGuid()";
...
engine.AddReference(typeof(System.Guid).Assembly);
engine.ImportNamespace("System");
...
dynamic d = engine.CreateSession().Execute(script);
Based on the question in your comment, there are code injection vulnerabilities. Add the System reference and namespace as shown right above, then replace the str with:
string str =
#" a=1, oops = (new Func<int>(() => {
Console.WriteLine(
""Security incident!!! User {0}\\{1} exposed "",
Environment.UserDomainName,
Environment.UserName);
return 1;
})).Invoke() ";
The question you described is something like deserialization, that is, contructing objects from data form(like string, byte array, stream, etc). Hope this link helps: http://msdn.microsoft.com/en-us/library/vstudio/ms233843.aspx
Here's a solution using ExpandoObject to store it after parsing it yourself. Right now it adds all values as strings, but you could add some parsing to try to turn it into a double, int, or long (you'd probably want to try it in that order).
static dynamic Parse(string str)
{
IDictionary<String, Object> obj = new ExpandoObject();
foreach (var assignment in str.Split(','))
{
var sections = assignment.Split('=');
obj.Add(sections[0], sections[1]);
}
return obj;
}
Use it like:
dynamic d = Parse("a=1,b=2,c=3");
// d.a is "1"

C# preg_replace?

What is the PHP preg_replace in C#?
I have an array of string that I would like to replace by an other array of string. Here is an example in PHP. How can I do something like that in C# without using .Replace("old","new").
$patterns[0] = '/=C0/';
$patterns[1] = '/=E9/';
$patterns[2] = '/=C9/';
$replacements[0] = 'à';
$replacements[1] = 'é';
$replacements[2] = 'é';
return preg_replace($patterns, $replacements, $text);
Real men use regular expressions, but here is an extension method that adds it to String if you wanted it:
public static class ExtensionMethods
{
public static String PregReplace(this String input, string[] pattern, string[] replacements)
{
if (replacements.Length != pattern.Length)
throw new ArgumentException("Replacement and Pattern Arrays must be balanced");
for (var i = 0; i < pattern.Length; i++)
{
input = Regex.Replace(input, pattern[i], replacements[i]);
}
return input;
}
}
You use it like this:
class Program
{
static void Main(string[] args)
{
String[] pattern = new String[4];
String[] replacement = new String[4];
pattern[0] = "Quick";
pattern[1] = "Fox";
pattern[2] = "Jumped";
pattern[3] = "Lazy";
replacement[0] = "Slow";
replacement[1] = "Turtle";
replacement[2] = "Crawled";
replacement[3] = "Dead";
String DemoText = "The Quick Brown Fox Jumped Over the Lazy Dog";
Console.WriteLine(DemoText.PregReplace(pattern, replacement));
}
}
You can use .Select() (in .NET 3.5 and C# 3) to ease applying functions to members of a collection.
stringsList.Select( s => replacementsList.Select( r => s.Replace(s,r) ) );
You don't need regexp support, you just want an easy way to iterate over the arrays.
public static class StringManipulation
{
public static string PregReplace(string input, string[] pattern, string[] replacements)
{
if (replacements.Length != pattern.Length)
throw new ArgumentException("Replacement and Pattern Arrays must be balanced");
for (int i = 0; i < pattern.Length; i++)
{
input = Regex.Replace(input, pattern[i], replacements[i]);
}
return input;
}
}
Here is what I will use. Some code of Jonathan Holland but not in C#3.5 but in C#2.0 :)
Thx all.
You are looking for System.Text.RegularExpressions;
using System.Text.RegularExpressions;
Regex r = new Regex("=C0");
string output = r.Replace(text);
To get PHP's array behaviour the way you have you need multiple instances of `Regex
However, in your example, you'd be much better served by .Replace(old, new), it's much faster than compiling state machines.
Edit: Uhg I just realized this question was for 2.0, but I'll leave it in case you do have access to 3.5.
Just another take on the Linq thing. Now I used List<Char> instead of Char[] but that's just to make it look a little cleaner. There is no IndexOf method on arrays but there is one on List. Why did I need this? Well from what I am guessing, there is no direct correlation between the replacement list and the list of ones to be replaced. Just the index.
So with that in mind, you can do this with Char[] just fine. But when you see the IndexOf method, you have to add in a .ToList() before it.
Like this: someArray.ToList().IndexOf
String text;
List<Char> patternsToReplace;
List<Char> patternsToUse;
patternsToReplace = new List<Char>();
patternsToReplace.Add('a');
patternsToReplace.Add('c');
patternsToUse = new List<Char>();
patternsToUse.Add('X');
patternsToUse.Add('Z');
text = "This is a thing to replace stuff with";
var allAsAndCs = text.ToCharArray()
.Select
(
currentItem => patternsToReplace.Contains(currentItem)
? patternsToUse[patternsToReplace.IndexOf(currentItem)]
: currentItem
)
.ToArray();
text = new String(allAsAndCs);
This just converts the text to a character array, selects through each one. If the current character is not in the replacement list, just send back the character as is. If it is in the replacement list, return the character in the same index of the replacement characters list. Last thing is to create a string from the character array.
using System;
using System.Collections.Generic;
using System.Linq;

Categories

Resources