[英].net Regex Search and string.replace
我的xml文件大约7mb。 我必须从某些节点中删除一些无效字符。 有很多节点,例如“ title”,“ country”等等。
我的“ title”节点有31000个匹配项,并且花费了超过35分钟的时间。 我的项目要求不可接受,我该如何优化
方法调用
fileText = RemoveInvalidCharacters(fileText, "title", @"(&#[xX]?[A-Fa-f\d]+;)|[^\w\s\/\;\&\.@-]", "$1");
方法定义
private static string RemoveInvalidCharacters(string fileText, string nodeName, string regexPattern, string regexReplacement)
{
foreach (Match match in Regex.Matches(fileText, @"<" + nodeName + ">(.*)</" + nodeName + ">"))
{
var oldValue = match.Groups[0].Value;
var newValue = "<" + nodeName + ">" + Regex.Replace(match.Groups[1].Value, regexPattern, regexReplacement) +
"</" + nodeName + ">";
fileText = fileText.Replace(oldValue, newValue);
}
return fileText;
}
您可以使用System.Xml.Linq
命名空间中的工具来代替您使用Regex
来解析Xml文档,这本质上是更快,更容易使用。
这是一个示例程序,它采用的结构包含35,000个节点。我保留了您的regex字符串以检查不良字符,但我将其指定为Compiled
regex字符串,这应该会产生更好的性能,尽管公认的是,当我将两者进行比较时,数量会大大增加。 更多信息 。
本示例使用Descendants
,它获取对您在指定元素内的参数中指定的所有元素的引用(在本例中,我们从根元素开始)。 这些结果通过ContainsBadCharacters
方法进行过滤。
为了简单起见,我没有将foreach
循环设为DRY,但是这样做可能是值得的。
在我的计算机上,此过程运行的时间不到一秒钟,但是时间会根据计算机的性能和不良字符的出现而有所不同。
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml.Linq;
namespace ConsoleApplication2
{
class Program
{
static Regex r = new Regex(@"(&#[xX]?[A-Fa-f\d]+;)|[^\w\s\/\;\&\.@-]", RegexOptions.Compiled);
static void Main(string[] args)
{
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
var xmls = new StringBuilder("<Nodes>");
for(int i = 0;i<35000;i++)
{
xmls.Append(@"<Node>
<Title>Lorem~~~~</Title>
<Country>Ipsum!</Country>
</Node>");
}
xmls.Append("</Nodes>");
var doc = XDocument.Parse(xmls.ToString());
sw.Start();
foreach(var element in doc.Descendants("Title").Where(ContainsBadCharacters))
{
element.Value = r.Replace(element.Value, "$1");
}
foreach (var element in doc.Descendants("Country").Where(ContainsBadCharacters))
{
element.Value = r.Replace(element.Value, "$1");
}
sw.Stop();
var saveFile = new FileInfo(Path.Combine(Assembly.GetExecutingAssembly().Location.Substring(0,
Assembly.GetExecutingAssembly().Location.LastIndexOf(@"\")), "test.txt"));
if (!saveFile.Exists) saveFile.Create();
doc.Save(saveFile.FullName);
Console.WriteLine(sw.Elapsed);
Console.Read();
}
static bool ContainsBadCharacters(XElement item)
{
return r.IsMatch(item.Value);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.