c# - Finding/editing exact entry in file -
i'm trying make changes file , appear need regex. have following code:
public delegate string updateaction(string contents); public static void updatefile(string file, updateaction m) { string contents = ""; using (streamreader reader = new streamreader(file)) contents = reader.readtoend(); contents = m(contents); using (streamwriter writer = new streamwriter(file)) writer.writeline(contents); } public static void updateproperty(string file, string objectname, string property, string value) { updatefile(file, delegate(string contents) { string propertypattern = "(\"" + property + "\".*?\")(.*?)(\")"; string pattern = "(\"?)" + objectname + "(\"?)(\n|\r|\r\n)(.*?){(.*?)}"; regexoptions options = regexoptions.singleline | regexoptions.multiline | regexoptions.ignorecase; contents = new regex(pattern, options).replace(contents, (matchevaluator)(m => new regex(propertypattern, options).replace(m.value, delegate(match propertymatch) { string str = propertymatch.value; if (propertymatch.groups.count > 3) { str = propertymatch.groups[1] + value + propertymatch.groups[3]; } return str; }))); return contents; }); }
an example file this:
"resource/hudlayout.res" { circle { "visible" "0" "enabled" "0" "controlname" "cexlabel" "fieldname" "circle" "zpos" "2" "xpos" "c-100" "ypos" "c-96" "wide" "201" "tall" "200" "font" "crosshairs34" //crosshairsoutline34 "labeltext" "9" "textalignment" "center" "fgcolor" "crosshair" } circledot { "visible" "0" "enabled" "0" "controlname" "cexlabel" "fieldname" "circledot" "zpos" "2" "xpos" "c-100" "ypos" "c-96" "wide" "201" "tall" "200" "font" "crosshairs34" //crosshairsoutline34 "labeltext" "8" "textalignment" "center" "fgcolor" "crosshair" } quartercircle { "visible" "0" "enabled" "0" "controlname" "cexlabel" "fieldname" "quartercircle" "zpos" "2" "xpos" "c-100" "ypos" "c-98" "wide" "201" "tall" "200" "font" "crosshairs34" //crosshairsoutline34 "labeltext" "w" "textalignment" "center" "fgcolor" "crosshair" } }
when call updateproperty(@"c:\file.res", "circle", "enabled", "1");
it's matching circle , quartercircle , setting enabled
property 1
both. i'm not great regex , wondering pattern should using catch object i'm searching for.
your regexes not formed correctly because forgot escape slashes (that why you'd rather use verbatim string literals when defining regex pattern), , main problem missing word boundaries \b
.
here update should work (tested, , expected entry modified):
string propertypattern = @"(""\b" + regex.escape(property) + @"\b"".*?"")(.*?)("")"; string pattern = @"(""?)\b" + regex.escape(objectname) + @"\b(""?)(\r\n|\n|\r)(.*?){(.*?)}"; regexoptions options = regexoptions.singleline | regexoptions.ignorecase;
i doubt need specify multiline
flag since not using ^
, $
in patterns.
i added regex.escape(property)
in case there special characters in argument pass (then there can problem \b
, hope won't case).
also, match type of newline, need use (\r\n|\n|\r)
longest part should come first, or never tested against.
Comments
Post a Comment