c# – 如何加速循环?是否有一个课程来替换多个术语?
循环:
var pattern = _dict[key]; string before; do { before = pattern; foreach (var pair in _dict) if (key != pair.Key) pattern = pattern.Replace(string.Concat("{",pair.Key,"}"),string.Concat("(",pair.Value,")")); } while (pattern != before); return pattern; 它只是在一堆键上重复查找和替换.字典只是< string,string>. 我可以看到2个改进. >每次我们执行pattern.Replace它再次从字符串的开头搜索.如果它碰到第一个{,它只会查看匹配的键列表(可能使用二进制搜索),然后替换适当的一个,那会更好. 但是……我真的不想写一个很讨厌的东西来做这一切.这必须是一个相当普遍的情况?有没有现成的解决方案? 全班 感谢Elian Ebbing和ChrisWue. class FlexDict : IEnumerable<KeyValuePair<string,string>> { private Dictionary<string,string> _dict = new Dictionary<string,string>(); private static readonly Regex _re = new Regex(@"{([_a-z][_a-z0-9-]*)}",RegexOptions.Compiled | RegexOptions.IgnoreCase); public void Add(string key,string pattern) { _dict[key] = pattern; } public string Expand(string pattern) { pattern = _re.Replace(pattern,match => { string key = match.Groups[1].Value; if (_dict.ContainsKey(key)) return "(" + Expand(_dict[key]) + ")"; return match.Value; }); return pattern; } public string this[string key] { get { return Expand(_dict[key]); } } public IEnumerator<KeyValuePair<string,string>> GetEnumerator() { foreach (var p in _dict) yield return new KeyValuePair<string,string>(p.Key,this[p.Key]); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } 示例用法 class Program { static void Main(string[] args) { var flex = new FlexDict { {"h",@"[0-9a-f]"},{"nonascii",@"[200-377]"},{"unicode",@"{h}{1,6}(rn|[ trnf])?"},{"escape",@"{unicode}|[^rnf0-9a-f]"},{"nmstart",@"[_a-z]|{nonascii}|{escape}"},{"nmchar",@"[_a-z0-9-]|{nonascii}|{escape}"},{"string1",@"""([^nrf""]|{nl}|{escape})*"""},{"string2",@"'([^nrf']|{nl}|{escape})*'"},{"badstring1",@"""([^nrf""]|{nl}|{escape})*?"},{"badstring2",@"'([^nrf']|{nl}|{escape})*?"},{"badcomment1",@"/*[^*]**+([^/*][^*]**+)*"},{"badcomment2",@"/*[^*]*(*+[^/*][^*]*)*"},{"baduri1",@"url({w}([!#$%&*-[]-~]|{nonascii}|{escape})*{w}"},{"baduri2",@"url({w}{string}{w}"},{"baduri3",@"url({w}{badstring}"},{"comment",@"/*[^*]**+([^/*][^*]**+)*/"},{"ident",@"-?{nmstart}{nmchar}*"},{"name",@"{nmchar}+"},{"num",@"[0-9]+|[0-9]*.[0-9]+"},{"string",@"{string1}|{string2}"},{"badstring",@"{badstring1}|{badstring2}"},{"badcomment",@"{badcomment1}|{badcomment2}"},{"baduri",@"{baduri1}|{baduri2}|{baduri3}"},{"url",@"([!#$%&*-~]|{nonascii}|{escape})*"},{"s",@"[ trnf]+"},{"w",@"{s}?"},{"nl",@"n|rn|r|f"},{"A",@"a| {0,4}(41|61)(rn|[ trnf])?"},{"C",@"c| {0,4}(43|63)(rn|[ trnf])?"},{"D",@"d| {0,4}(44|64)(rn|[ trnf])?"},{"E",@"e| {0,4}(45|65)(rn|[ trnf])?"},{"G",@"g| {0,4}(47|67)(rn|[ trnf])?|g"},{"H",@"h| {0,4}(48|68)(rn|[ trnf])?|h"},{"I",@"i| {0,4}(49|69)(rn|[ trnf])?|i"},{"K",@"k| {0,4}(4b|6b)(rn|[ trnf])?|k"},{"L",@"l| {0,4}(4c|6c)(rn|[ trnf])?|l"},{"M",@"m| {0,4}(4d|6d)(rn|[ trnf])?|m"},{"N",@"n| {0,4}(4e|6e)(rn|[ trnf])?|n"},{"O",@"o| {0,4}(4f|6f)(rn|[ trnf])?|o"},{"P",@"p| {0,4}(50|70)(rn|[ trnf])?|p"},{"R",@"r| {0,4}(52|72)(rn|[ trnf])?|r"},{"S",@"s| {0,4}(53|73)(rn|[ trnf])?|s"},{"T",@"t| {0,4}(54|74)(rn|[ trnf])?|t"},{"U",@"u| {0,4}(55|75)(rn|[ trnf])?|u"},{"X",@"x| {0,4}(58|78)(rn|[ trnf])?|x"},{"Z",@"z| {0,4}(5a|7a)(rn|[ trnf])?|z"},{"CDO",@"<!--"},{"CDC",@"-->"},{"INCLUDES",@"~="},{"DASHMATCH",@"|="},{"STRING",@"{string}"},{"BAD_STRING",@"{badstring}"},{"IDENT",@"{ident}"},{"HASH",@"#{name}"},{"IMPORT_SYM",@"@{I}{M}{P}{O}{R}{T}"},{"PAGE_SYM",@"@{P}{A}{G}{E}"},{"MEDIA_SYM",@"@{M}{E}{D}{I}{A}"},{"CHARSET_SYM",@"@charsetb"},{"IMPORTANT_SYM",@"!({w}|{comment})*{I}{M}{P}{O}{R}{T}{A}{N}{T}"},{"EMS",@"{num}{E}{M}"},{"EXS",@"{num}{E}{X}"},{"LENGTH",@"{num}({P}{X}|{C}{M}|{M}{M}|{I}{N}|{P}{T}|{P}{C})"},{"ANGLE",@"{num}({D}{E}{G}|{R}{A}{D}|{G}{R}{A}{D})"},{"TIME",@"{num}({M}{S}|{S})"},{"PERCENTAGE",@"{num}%"},{"NUMBER",@"{num}"},{"URI",@"{U}{R}{L}({w}{string}{w})|{U}{R}{L}({w}{url}{w})"},{"BAD_URI",@"{baduri}"},{"FUNCTION",@"{ident}("},}; var testStrings = new[] { @"""str""",@"'str'","5","5.","5.0","a","alpha","url(hello)","url("hello")","url("blah)",@"g",@"/*comment*/",@"/**/",@"<!--",@"-->",@"~=","|=",@"#hash","@import","@page","@media","@charset","!/*iehack*/important"}; foreach (var pair in flex) { Console.WriteLine("{0}nt{1}n",pair.Value); } var sw = Stopwatch.StartNew(); foreach (var str in testStrings) { Console.WriteLine("{0} matches: ",str); foreach (var pair in flex) { if (Regex.IsMatch(str,"^(" + pair.Value + ")$",RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture)) Console.WriteLine(" {0}",pair.Key); } } Console.WriteLine("nRan in {0} ms",sw.ElapsedMilliseconds); Console.ReadLine(); } } 目的 用于构建可能相互扩展的复杂正则表达式.也就是说,我正在尝试实施the css spec. 解决方法
我认为如果你使用正则表达式查找{foo}的任何出现会更快,然后使用
MatchEvaluator替换{foo},如果foo恰好是字典中的键.
我目前没有视觉工作室,但我想这在功能上与您的代码示例相同: var pattern = _dict[key]; bool isChanged = false; do { isChanged = false; pattern = Regex.Replace(pattern,"{([^}]+)}",match => { string matchKey = match.Groups[1].Value; if (matchKey != key && _dict.ContainsKey(matchKey)) { isChanged = true; return "(" + _dict[matchKey] + ")"; } return match.Value; }); } while (isChanged); 我可以问你为什么需要do / while循环吗?字典中键的值是否可以再次包含必须替换的{占位符}?你能确定你不会陷入无限循环,其中键“A”包含“Blahblah {B}”而键“B”包含“Blahblah {A}”吗? 编辑:进一步的改进将是: >使用预编译的正则表达式. 你最终会得到一个O(n)算法,其中n是输出的大小,所以你不能做得比这更好. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- c# – 在nulls和string.Empty上使用==或.Equals()
- xml – 修改节点和所有子节点中属性的子字符串
- flex chart 去水印 flex data visualization trial 亲自用过
- 如何使用 CoCreateGUID API 生成与 VB 6 的 GUID
- c# – Convert.ToString返回string.empty而不是null
- Flash入门应该了解的重要概念
- c# – 当TabControl的ItemsSource绑定到WPF中的列表时,如何
- 设计模式六大原则(3):依赖倒置原则
- UML------依赖、泛化、实现、聚合、组合、关联
- c – 如何实现平滑切线空间法线?