查找/编辑文件

时间:2015-05-12 07:10:25

标签: c# regex

我试图对文件进行更改,我似乎需要一些正则表达式的帮助。我有以下代码:

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

示例文件看起来像这样:

"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"
    }
}

当我致电UpdateProperty(@"C:\file.res", "Circle", "enabled", "1");时,它匹配和季度,并将enabled属性设置为1对彼此而言。我对正则表达式并不满意,并且想知道我应该使用什么模式来捕捉我正在搜索的对象。

2 个答案:

答案 0 :(得分:2)

你的正则表达式没有正确形成,因为你忘了逃避斜杠(这就是为什么你在定义正则表达式模式时更喜欢使用逐字字符串文字),主要问题是缺少单词边界{{1 }}

这是一个应该有效的更新(经过测试,只修改了预期的条目):

\b

我还怀疑您需要指定string propertyPattern = @"(""\b" + Regex.Escape(property) + @"\b"".*?"")(.*?)("")"; string pattern = @"(""?)\b" + Regex.Escape(objectName) + @"\b(""?)(\r\n|\n|\r)(.*?){(.*?)}"; RegexOptions options = RegexOptions.Singleline | RegexOptions.IgnoreCase; 标记,因为您的模式中没有使用Multiline^

我还添加了$,以防你传递的参数中有任何特殊字符(然后Regex.Escape(property)会出现问题,但我希望不会出现这种情况)。

此外,要匹配任何类型的换行符,您需要使用\b,其中最长的部分应该首先出现,否则永远不会对其进行测试。

答案 1 :(得分:1)

更新此行(添加\\W模式):

string pattern = "\\W(\"?)" + objectName + "(\"?)(\n|\r|\r\n)(.*?){(.*?)}";