Match and replace - c#

I have a long string and within that string I have the following text:
"formatter": "SomeInformationHere"
I need to find the above text within the long string and remove the double quote marks around SomeInformationHere so the result looks like the below, but the quotes around the word "formatter" must remain.
"formatter": SomeInformationHere
I tried the below, which finds the string, but I'm not sure how to replace just the quotation marks around the value SomeInformationHere:
string pattern = "\"formatter\": ([\"]).*([\"])";
Match match = Regex.Match(myString, pattern, RegexOptions.IgnoreCase);
//Replace text in "myString" here
myString = ?????
//Output match value:
Response.Write(match.Value);
Edit: Oh I forgot to mention that the above pattern could be in the "mystring" more than once and all will need the replacement doing on them.
Edit 2:
I've had a look at the regex tester site (thanks for the link) and pasted in my test string and regex pattern, it seems to work in that, but when I put the same pattern into dot net the replacement seems to work as if the "singleline" option has been selected. Below is the code I've used.
The string - note that this does NOT contain any carriage returns - it's one long string that has been built from an XML file. Formatted for readability.
{
"chart": {
"borderRadius": 15,
"borderWidth": 1,
"renderTo": "ChartContainer1",
"type": "pie"
},
"credits": {
"enabled": false
},
"labels": {
"items": [{
"html": "Label 1",
"style": {
"left": "10px",
"top": "30px"
}
}, {
"html": "Label 2",
"style": {
"left": "10px",
"top": "50px"
}
}, {
"dummy": null
}]
},
"plotOptions": {
"pie": {
"allowPointSelect": true,
"cursor": "pointer",
"showInLegend": true
}
},
"series": [{
"data": [{
"name": "Firefox",
"y": 45.0
}, {
"name": "IE",
"y": 26.8
}, {
"name": "Chrome",
"selected": true,
"sliced": true,
"y": 12.8
}, {
"name": "Safari",
"y": 8.5
}, {
"name": "Opera",
"y": 6.2
}, {
"name": "Others",
"y": 0.7
}],
"name": "Browser share"
}, {
"dummy": null
}],
"test": {
"formatter": "function(){return \u0027\u0027+ this.point.name +\u0027<\/b>: \u0027+ this.y +\u0027 %\u0027;}"
},
"title": {
"align": "center",
"text": "Your chart title here"
},
"tooltip": {
"formatter": "function(){return \u0027\u0027+ this.point.name +\u0027<\/b>: \u0027+ this.y +\u0027 %\u0027;}"
}
}
As you can see near the bottom next to "test" and "tooltip" I have the "formatter:" part. the patten I'm currently using works when the above string is all on several lines (with CRs) in the tester, but when I put it on ONE line like it should be then the pattern doens't work
The .NET code / pattern I'm using is:
string pattern = "(\"formatter\": )\"(.*)\"( })";
var regex = new Regex(pattern, RegexOptions.IgnoreCase);
aJSON = regex.Replace(aJSON, "$1$2$3");
thanks again. but I still can't seem to get the pattern to work correctly in the tester.
Target string in the REGex tester site: (with no CRs)
{"chart": {"borderRadius": 15, "borderWidth": 1, "renderTo": "ChartContainer1", "type": "pie" }, "credits": {"enabled": false }, "labels": { "items": [ {"html": "Label 1", "style": {"left": "10px", "top": "30px" } }, {"html": "Label 2", "style": {"left": "10px", "top": "50px" } }, {"dummy": null } ] }, "plotOptions": {"pie": {"allowPointSelect": true, "cursor": "pointer", "showInLegend": true } }, "series": [ { "data": [ {"name": "Firefox", "y": 45.0 }, {"name": "IE", "y": 26.8 }, {"name": "Chrome", "selected": true, "sliced": true, "y": 12.8 }, {"name": "Safari", "y": 8.5 }, {"name": "Opera", "y": 6.2 }, {"name": "Others", "y": 0.7 } ], "name": "Browser share" }, {"dummy": null } ], "test": {"formatter": "function(){return \u0027\u0027+ this.point.name +\u0027<\/b>: \u0027+ this.y +\u0027 %\u0027;}" }, "title": {"align": "center", "text": "Your chart title here" }, "tooltip": {"formatter": "function(){return \u0027\u0027+ this.point.name +\u0027<\/b>: \u0027+ this.y +\u0027 %\u0027;}" } }
I've now found the correct pattern that seems to work and find multiple matches in the string. Posting it here for completion.
string pattern = "(\"formatter\": )\"(.[^\"]*)\"";

Everybody else has pretty much nailed it with using capturing groups and substitutions, just wanted to provide a little more context:
The main two things that are used here are Named Capturing Groups and Substitutions
static void Main(string[] args) {
var input = new[] {
"\"formatter\": \"John\"",
"\"formatter\": \"Sue\"",
"\"formatter\": \"Greg\""
};
foreach (var s in input) {
System.Console.Write("Original: [{0}]{1}", s, Environment.NewLine);
System.Console.Write("Replaced: [{0}]{1}", ReFormat(s), Environment.NewLine);
System.Console.WriteLine();
}
System.Console.ReadKey();
}
private static String ReFormat(String str) {
//Use named capturing groups to make life easier
var pattern = "(?<label>\"formatter\"): ([\"])(?<tag>.*)([\"])";
//Create a substitution pattern for the Replace method
var replacePattern = "${label}: ${tag}";
return Regex.Replace(str, pattern, replacePattern, RegexOptions.IgnoreCase);
}

You can use the Regex.Replace method like this:
string pattern = "\"formatter\": \"(.*)\"";
myString = Regex.Replace(myString, pattern, "\"formatter\": $1");

Use this:
string longString = #"""formatter"": ""SomeInformationHere""";
string pattern = "(\"formatter\": )([\"])(.*)([\"])";
string result = Regex.Replace(longString, pattern, "$1$3");
This replaces all found matches with the second and the fourth sub group of the match. The complete match is the first sub group ($0) and all parts in parenthesis create a new sub group.

Most probably "the replacement seems to work as if the "singleline" option has been selected" beacause the initially used by you regex will match correctly up to the 14th symbol in
**"formatter": "SomeInformationHere"**
, but after that it will match every symbol nomatter what it is, including the next fist occurance of double quotes, and it will continue untill the first new line. That's how .* expression works because of it's greedness (Check greedy vs lazy regex).
So I suppose that you have only to modify
"\"formatter\": ([\"]).*([\"])"
to
"\"formatter\": ([\"]).*?([\"])"

var pattern = #"^(\s*""formatter""\s*:\s*)[""](.*)[""](\s)*$";
var regex = new Regex(pattern, RegexOptions.Compiled | RegexOptions.Multiline);
myString = regex.Replace(myString, "$1$2$3");

Related

I want to calculate the json file before post to Cosmos db. cosmos will allow max 2mb file size. How it possible in c#?

I have a json looks below. I want to calculate the size of the json in c# that I got from frontend. I will store the json in cosmos db.
My json is:
{
"employeecode": "E1001",
"Employeename": "xyz",
"Address": [
{
"RowID": "1",
"Address1": "58-8",
"Address2": "rachel street",
"City": "Newyork",
"Pin": "100981"
}
],
"Exp": [],
"Education": [
{
"RowID": "1",
"Secondary": "87.8",
"School": "xyz",
"City": "abc"
},
{
"RowID": "2",
"Higher Secondary": "87.8",
"School": "xyz",
"City": "abc"
},
{
"RowID": "3",
"Btech": "8.8",
"college": "xyz",
"City": "abc"
}
]
}
How can I calculte the size of json in c#?
There are different ways to find the string size and it depends on the encoding of your string Unicode or UTF-8. The easiest way is using System.Text.Encoding
If it is encoded with UTF-8
var size_in_MB1 = Math.Round(((decimal)Encoding.UTF8.GetByteCount(json) / 1048576), 2);
And, if it is encoded with Unicode
var size_in_MB2 = Math.Round(((decimal)Encoding.Unicode.GetByteCount(json) / 1048576), 2);

String.Format in foreach loop for printing in the same line

I have a function with which I read a Json and deserialize it. The JSON is nested and what I want is to print some nested values in the same line.
My JSON is that:
{
"number": 123,
"person": [{
"phone": 864556,
"name": "John D",
"address": "N.Y",
"email": "test#test.com"
},
{
"phone": 19845,
"name": "Mary S",
"address": "N.Y",
"email": "testmary#test.com"
},
{
"phone": 34936,
"name": "Alex N",
"address": "Santiago",
"email": "alex#test.com"
},
{
"phone": 197478,
"name": "Bill McK",
"address": "London",
"email": "test#example.com"
}]
}
and I have this
foreach (var num in JMain.person)
{
debugOutput(String.Format("<{0};>", num.phone));
}
private void debugOutput(string strDebugText)
{
try
{
outPut += strDebugText + Environment.NewLine;
System.Diagnostics.Debug.Write(strDebugText + Environment.NewLine);
}
catch(Exception ex)
{
System.Diagnostics.Debug.Write(ex.Message.ToString() + Environment.NewLine);
}
}
where debugOutput is the function in which I read the JSON and print it. What I want is to print all the phones in one line. With for loop and String.Format I can print them one down the other. Maybe isn't right to use String.Format and there is another way?
Thank you
If you want all the output in one string, you could do it like this. Depending on what's in your debugOutput function, there might be easier ways though.
string outputstring = "";
foreach (var num in JMain.person)
{
outputstring += String.Format("<{0};>", num.phone);
}
debugOutput(outputstring);
If you want to make a single string from multiple parts, use string.Join:
var phones = string.Join("", JMain.person.Select(num => string.Format("<{0};>", num.phone));
First argument of Join is separator. Use "" if you do not want any separation between individual formatted strings.
The above replaces your foreach loop. Print phones on a single line with
debugOutput(phones);
The other answers are valid, but for your code, the issue is your use of NewLine:
private void debugOutput(string strDebugText)
{
try
{
System.Diagnostics.Debug.Write(strDebugText);
}
catch(Exception ex)
{
System.Diagnostics.Debug.Write(ex.Message.ToString());
}
}

Update Single JSON Value Based on Key

Experts,
I have a question regarding updating a specific value not based on the index path of the JSON file. For example with the JSON below, with the first set of businesses, I want to update "SubscribeStatus to "true" based on another value like the "1" value of the Key "ID". Is this possible, and how would I achieve this?
High Level Logic:
if (ID == 1)
SubscribeStatus (for first set of businesses) = true
if (ID == 2)
SubscribeStatus (for second set of businesses) = false
JSON:
{"Business":
[
{
"ID": 1,
"Name_Location": "A Name Location",
"Brief_Name_Location": "A Brief Name Location",
"Full_Address": "A Address",
"Latitude": 0.0,
"Longitude": 0.0,
"Phone": 123456789,
"Website": "www.google.com",
"SubscribeStatus":false,
"Logo": "Alogo.png",
},
{
"ID": 2,
"Name_Location": "B Name Location",
"Brief_Name_Location": "B Brief Name Location",
"Full_Address": "B Address",
"Latitude": 1.0,
"Longitude": 1.0,
"Phone": 987654321,
"Website": "www.yahoo.com",
"SubscribeStatus":true,
"Logo": "Blogo.png",
},
]
}

Regex to find a specific pattern

{
"rows": 10,
"os": "0",
"page": "1",
"total": "1",
"peoples": {
"123": {
"url": "http://google.com",
"id": "123",
"fname": "Rob",
"lname": "Tom",
"full_name_ac": "Rob Tom"
}
}
}
I am trying to write a regex to get a full name in c# something like /("full_name_ac": ")\w+, but not able to write.Please help me to write the regex that will always find the value under double quotes for full_name_ac
Your RegEx to extract a full_name_acvalue out of this string should look like
(?<="full_name_ac": ")[\w\ ]+(?=\")
Explaination:
(?<="full_name_ac": ") - starts with "full_name_ac": " but it's not a part of the value
[\w\ ]+ the name including space with at lease one character
(?=\") and the string has to end with a " which isn't a part of the value

Convert json string to value

I have two json string and also posted here. First json string convert from c# data table using newtonsoft dll. The second one is manual string. If i use the second string means chart displayed well. First one means chart not displayed. I just found the error "value" and "y" like a string in first json string. Kindly help me to change the first one to second one.
1)
[
{
"name": "CHE-CORPORATE",
"value": "42",
"y": "11.8"
},
{
"name": "CHE-TELUGU",
"value": "123",
"y": "10.8"
},
{
"name": "CHE-MALAYALAM",
"value": "13",
"y": "23.8"
}
]
2)
[
{ "name": "CHE-TELUGU",
"value": 123,
"y": 10.8
},
{
"name": "CHE-CORPORATE",
"value": 45,
"y": 40.8
},
{
"name": "CHE-MALAYALAM",
"value": 155,
"y": 12.8
}
]
Just convert the string to number
$.each(data,function(key,val){
val.value=+val.value; // convert the string to number
val.y=+val.y;
});
console.log(data);
Demo

Categories

Resources