Harag
Harag

Reputation: 1582

Match and replace

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.

  1. 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\": )\"(.[^\"]*)\"";

Upvotes: 36

Views: 102048

Answers (5)

rusty
rusty

Reputation: 2789

You can use the Regex.Replace method like this:

string pattern = "\"formatter\": \"(.*)\"";
myString = Regex.Replace(myString, pattern, "\"formatter\": $1");

Upvotes: 19

0xC0DEGURU
0xC0DEGURU

Reputation: 1792

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\": ([\"]).*?([\"])"

Upvotes: 1

František Žiačik
František Žiačik

Reputation: 7612

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

Upvotes: 0

Josh
Josh

Reputation: 44906

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

Upvotes: 39

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174279

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.

Upvotes: 4

Related Questions