如何提高正则表达式的性能?

时间:2014-10-31 11:11:59

标签: c# .net regex

我有一些问题。 我需要在string中替换一些文本:

var str = "<tr class=\"fieldType\"><td><a href=\"#\" onclick=\"javascript:removeNestedForm(this,&#39;tr.fieldType&#39;,&#39;.mark-for-delete&#39;,false);return false;\">Удалить</a><input data-val=\"true\" data-val-number=\"The field Id must be a number.\" data-val-required=\"The Id field is required.\" id=\"FieldTypes[0]_635503397304941429__Id\" name=\"nestedObject.Id\" type=\"hidden\" value=\"0\" /><input data-val=\"true\" data-val-number=\"The field DocTypeId must be a number.\" data-val-required=\"The DocTypeId field is required.\" id=\"FieldTypes[0]_635503397304941429__DocTypeId\" name=\"nestedObject.DocTypeId\" type=\"hidden\" value=\"0\" /><input class=\"mark-for-delete\" data-val=\"true\" data-val-required=\"The IsDel field is required.\" id=\"FieldTypes[0]_635503397304941429__IsDel\" name=\"nestedObject.IsDel\" type=\"hidden\" value=\"False\" /><input data-val=\"true\" data-val-required=\"The CanDel field is required.\" id=\"FieldTypes[0]_635503397304941429__CanDel\" name=\"nestedObject.CanDel\" type=\"hidden\" value=\"True\" />    </td>    <td>        <select id=\"FieldTypes[0]_635503397304941429__Convertion\" name=\"nestedObject.Convertion\" style=\"width:99%;\"><option value=\"int\">int</option><option value=\"string\">string</option></select></td><td><input data-val=\"true\" data-val-required=\"Название не может быть пустым\" id=\"FieldTypes[0]_635503397304941429__Name\" name=\"nestedObject.Name\" style=\"width:99%;\" type=\"text\" value=\"\"></td><td><input id=\"FieldTypes[0]_635503397304941429__Description\" name=\"nestedObject.Description\" style=\"width:99%;\" type=\"text\" value=\"\" /></td></tr>";

我使用方法:

private static string ReplaceAttribute(string source, string name, string found, string replaced)
{
    string pattern = string.Format(@"({0}=[\\""]*(\w*[._\[\]]?)*)({1})", name, found);
    string replacement = "$1" + replaced;

    var theRegex = new Regex(pattern, RegexOptions.Compiled | RegexOptions.Singleline);
    var result = theRegex.Replace(source, replacement);

    return result;
}

我的代码工作了很长时间:

strPartial = ReplaceAttribute(strPartial, "id", propertyNameFake, collectionProperty + "_" + ticks + "_");
strPartial = ReplaceAttribute(strPartial, "name", propertyNameFake, collectionProperty + "[" + ticks + "]");
strPartial = ReplaceAttribute(strPartial, "data-valmsg-for", propertyNameFake, collectionProperty + "[" + ticks + "]");

如何提高正则表达式的性能? 感谢。

1 个答案:

答案 0 :(得分:2)

您正在寻找反斜杠和引号,但代码中的引号之前没有反斜杠,仅在C#字符串文字中。只需查找引号,即""?而不是[\\""]*。 (另请注意,\\分隔字符串中的@最终为字符串中的\\,而不是\。)

但真正的实际问题来自于此。您有相互嵌套的条件值,即可选的字母数字后跟可选的分隔符,重复零次或多次:(\w*[._\[\]]?)*)。相反,您应该只使用带有字符的集合:[\w\._\[\]]*

当匹配字符串时,条件值将通过尽可能匹配开始,然后回溯以找到模式其余部分匹配的最长匹配。对于嵌套条件,将会有大量的回溯。

当我使用示例字符串测试更改时,代码运行速度提高了大约600倍(11毫秒而不是6240毫秒)。