12

Problem:

Cannot find a consistent way to replace a random string between quotes with a specific string I want. Any help would be greatly appreciated.

Example:

String str1 = "test=\"-1\"";

should become

String str2 = "test=\"31\"";

but also work for

String str3 = "test=\"foobar\"";

basically I want to turn this

String str4 = "test=\"antyhingCanGoHere\"";

into this

String str4 = "test=\"31\"";

Have tried:

Case insensitive Regex without using RegexOptions enumeration

How do you do case-insensitive string replacement using regular expressions?

Replace any character in between AnyText: and <usernameredacted@example.com> with an empty string using Regex?

Replace string in between occurrences

Replace a String between two Strings

Current code:

    Regex RemoveName = new Regex("(?VARIABLE=\").*(?=\")", RegexOptions.IgnoreCase);
    String convertSeccons = RemoveName.Replace(ruleFixed, "31");

Returns error:

System.ArgumentException was caught
  Message=parsing "(?VARIABLE=").*(?=")" - Unrecognized grouping construct.
  Source=System
  StackTrace:
       at System.Text.RegularExpressions.RegexParser.ScanGroupOpen()
       at System.Text.RegularExpressions.RegexParser.ScanRegex()
       at System.Text.RegularExpressions.RegexParser.Parse(String re, RegexOptions op)
       at System.Text.RegularExpressions.Regex..ctor(String pattern, RegexOptions options, Boolean useCache)
       at System.Text.RegularExpressions.Regex..ctor(String pattern, RegexOptions options)
       at application.application.insertGroupID(String rule) in C:\Users\winserv8\Documents\Visual Studio 2010\Projects\application\application\MainFormLauncher.cs:line 298
       at application.application.xmlqueryDB(String xmlSaveLocation, TextWriter tw, String ruleName) in C:\Users\winserv8\Documents\Visual Studio 2010\Projects\application\application\MainFormLauncher.cs:line 250
  InnerException: 

found answer

string s = Regex.Replace(ruleFixed, "VARIABLE=\"(.*)\"", "VARIABLE=\"31\"");
ruleFixed = s;

I found this code sample at Replace any character in between AnyText: and with an empty string using Regex? which is one of the links i previously posted and just had skipped over this syntax because i thought it wouldnt handle what i needed.

Community
  • 1
  • 1
toosweetnitemare
  • 2,226
  • 8
  • 33
  • 44

11 Answers11

3
var str1 = "test=\"foobar\"";
var str2 = str1.Substring(0, str1.IndexOf("\"") + 1) + "31\"";

If needed add check for IndexOf != -1

ErikE
  • 48,881
  • 23
  • 151
  • 196
Magnus
  • 45,362
  • 8
  • 80
  • 118
  • This doesn't meet his use case of searching for a particular value. – ErikE Jan 08 '13 at 22:20
  • @ErikE He does not want to search for a particular value but rather replace a random value inside the quotes – Magnus Jan 08 '13 at 22:22
  • To clarify: this doesn't test for the format `test="foobar"`. It just finds any old `"foobar"`, even `donotchangethis="foobar"`. Plus, you're not replacing the contents of the original string but making a new one. The whole string he's replacing in can be many lines long! Not a matching scenario. – ErikE Jan 08 '13 at 22:23
  • 1
    @ErikE I'd say `donotchangethis="foobar"` should be changed since the requirement is to set any value inside quotes. Also there is no such thing as "replacing" since strings are immutable. – Magnus Jan 08 '13 at 22:28
  • I may have incorrectly believed there were other parts to the string beyond the single key/value pair. However, if you read the OP carefully (paying attention to his own solution presented) you will see that the requirement *is not* "any value inside quotes". – ErikE Jan 08 '13 at 22:35
  • @ErikE I suppose you could be right, but without looking at his not working code, and reading the question; "replace a random string between quotes with a specific string I want", one could assume _that_ is what he wants. – Magnus Jan 08 '13 at 22:39
2

I don't know if I understood you correct, but if you want to replace all chars inside string, why aren't you using simple regular expresission

String str = "test=\"-\"1\"";

Regex regExpr = new Regex("\".*\"", RegexOptions.IgnoreCase);
String result = regExpr.Replace(str , "\"31\"");

Console.WriteLine(result);

prints:

test="31"

Note: You can take advantage of plain old XAttribute

String ruleFixed = "test=\"-\"1\"";

var splited = ruleFixed.Split('=');
var attribute = new XAttribute(splited[0], splited[1]);

attribute.Value = "31";

Console.WriteLine(attribute);//prints test="31"
Ilya Ivanov
  • 23,148
  • 4
  • 64
  • 90
  • 1
    That's going to be too greedy, I expect. I'd suggest `[^"]*` instead. But it might not be, depending on the actual usecases... – Bobson Jan 08 '13 at 22:10
  • I know, I assume we need to be greedy, let me double-check. Well, he wrote `random string`. I will update to have two options – Ilya Ivanov Jan 08 '13 at 22:10
  • except escape the `"` in the capture group: `[^\"]*` – Steve Konves Jan 08 '13 at 22:12
  • the full regex is `\"[^\"]*\"` which is essentially anything that is not a double quote that is between two double quotes – Steve Konves Jan 08 '13 at 22:16
  • This doesn't test for the format `test="foobar"`. It just finds any old `"something"`, even `donotchangethis="foobar"`. – ErikE Jan 08 '13 at 22:17
  • true. the title from the OP just specifies between two quotes. you can add a positive lookbehind to it: `(?<=test=)\"[^\"]*\"` – Steve Konves Jan 08 '13 at 22:20
  • 1
    @Steve Is it normal answer questions based on title alone and not look at the explanation in the question text? – ErikE Jan 08 '13 at 22:22
  • @ErikE definitely not! However a response to an almost-correct comment on an actual answer is another matter :) – Steve Konves Jan 08 '13 at 22:26
  • @Steve I'm not sure what you're saying. In any case my comment above was not about your comment, but about the answer itself. – ErikE Jan 08 '13 at 22:37
1

In the case that your string has other things in it besides just the key/value pair of key="value", then you need to make the value-match part not match quote marks, or it will match all the way from the first value to the last quote mark in the string.

If that is true, then try this:

Regex.Replace(ruleFixed, "(?<=VARIABLE\s*=\s*\")[^\"]*(?=\")", "31");

This uses negative look-behind to match the VARIABLE=" part (with optional white space around it so VARIABLE = " would work as well, and negative look-ahead to match the ending ", without including the look-ahead/behind in the final match, enabling you to just replace the value you want.

If not, then your solution will work, but is not optimal because you have to repeat the value and the quote marks in the replace text.

ErikE
  • 48,881
  • 23
  • 151
  • 196
  • what about a positive lookbehind (variable name and preceding double quote) and lookahead (trailing double quote): `(?<=test\s*=\s*\")[^\"]*(?=\")` That way you could just make the replacement with the new value, rather than the whole string. – Steve Konves Jan 08 '13 at 22:37
  • You could also use ? - If you try to match .*? that will perform a non-greedy pattern match which won't include the closing quote – levelnis Jan 08 '13 at 22:39
  • @Steve I think that would be a superior answer, to replace only the part needing replacement. – ErikE Jan 08 '13 at 22:45
1
var parts = given.Split('=');
return string.Format("{0}=\"{1}\"", parts[0], replacement);
Austin Salonen
  • 49,173
  • 15
  • 109
  • 139
  • And if it starts with `wrongkey="value"` you've incorrectly replaced it rather than only paying attention to `rightkey="value"`. – ErikE Jan 08 '13 at 22:36
  • @ErikE: That assumes `given` was incorrectly found and not something this function would care about. – Austin Salonen Jan 08 '13 at 22:38
1

Assuming that the string within the quotes does not contain quotes itself, you can use this general pattern in order to find a position between a prefix and a suffix:

(?<=prefix)find(?=suffix)

In your case

(?<=\w+=").*?(?=")

Here we are using the prefix \w+=" where \w+ denotes word characters (the variable) and =" are the equal sign and the quote.

We want to find anything .*? until we encounter the next quote.

The suffix is simply the quote ".

string result = Regex.Replace(input, "(?<=\\w+=\").*?(?=\")", replacement);
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
0

Try this:

[^"\r\n]*(?:""[\r\n]*)*
Saleh Omar
  • 739
  • 2
  • 8
  • 29
  • I was thinking that way, too, based on the title, but the desire is only for quoted strings in the form `test="value"`, not just any old `"value"`. – ErikE Jan 08 '13 at 22:15
0
     String str1 = "test=\"-1\"";
     string res = Regex.Replace(str1, "(^+\").+(\"+)", "$1" + "31" + "$2");
VladL
  • 12,769
  • 10
  • 63
  • 83
0
var pattern = "\"(.*)?\"";
var regex = new Regex(pattern, RegexOptions.IgnoreCase);
var replacement = regex.Replace("test=\"hereissomething\"", "\"31\"");
levelnis
  • 7,665
  • 6
  • 37
  • 61
  • This will not work.. it returns "test=\"31\"" he wants the ending \"" to be removed to `yield "test=\"31\` – MethodMan Jan 08 '13 at 22:19
  • No he doesn't - unless I've completely misunderstood the question it looks as though he wants to replace strings that are between opening and closing quotes - both sets of quotes are present in the all examples in the question – levelnis Jan 08 '13 at 22:21
  • @levelnis He only wants strings that are introduced by a particular value as in `key1="whatever"`. He doesn't want to match `key2="whatever"`. – ErikE Jan 08 '13 at 22:28
  • @DJKRAZE I think you're misunderstanding the requirements. – ErikE Jan 08 '13 at 22:29
  • @levelins you could be right, and my apologies if so. I may have incorrectly believed that the input string had other values in it besides this one. – ErikE Jan 08 '13 at 22:33
  • I am not looking at this question I think the OP is confused on what he / she wants – MethodMan Jan 08 '13 at 22:35
0
string s = Regex.Replace(ruleFixed, "VARIABLE=\"(.*)\"", "VARIABLE=\"31\"");
ruleFixed = s;

I found this code sample at Replace any character in between AnyText: and <usernameredacted@example.com> with an empty string using Regex? which is one of the links i previously posted and just had skipped over this syntax because i thought it wouldnt handle what i needed.

Community
  • 1
  • 1
toosweetnitemare
  • 2,226
  • 8
  • 33
  • 44
  • This won't work correctly unless your `ruleFixed` string does not contain any other quote marks. Is that true? Please [see my answer](http://stackoverflow.com/a/14224924/57611) for how to stop matching when the value inside the quotes ends. – ErikE Jan 08 '13 at 22:30
0
String str1 = "test=\"-1\"";
string[] parts = str1.Split(new[] {'"'}, 3);
string str2 = parts.Length == 3 ? string.Join(@"\", parts.First(), "31", parts.Last()) : str1;
LucVK
  • 66
  • 2
0

Im pretty bad at RegEx but you could make a simple ExtensionMethod using string functions to do this.

public static class StringExtensions
{
    public static string ReplaceBetweenQuotes(this string str, string replacement)
    {
        if (str.Count(c => c.Equals('"')) == 2)
        {
            int start = str.IndexOf('"') + 1;
            str = str.Replace(str.Substring(start, str.LastIndexOf('"') - start), replacement);
        }
        return str;
    }
}

Usage:

 String str3 = "test=\"foobar\"";
 str3 = str3.ReplaceBetweenQuotes("31");

returns: "test=\"31\"" 
sa_ddam213
  • 42,848
  • 7
  • 101
  • 110