Ich habe ein Codebeispiel, wo eine MatchCollection das Programm zu hängen scheint, wenn es versucht, es mit Foreach zu verwenden.Kann eine MatchCollection das Programm beim Versuch, es zu iterieren, hängen?
ich css bin Parsen eine Klasse CSSParser mit:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Helpers.Extensions;
namespace Helpers.Utils
{
public class CSSParser
{
private readonly Dictionary<string, Dictionary<string, string>>
_dict = new Dictionary<string, Dictionary<string, string>>();
private const string SelectorKey = "selector";
private const string NameKey = "name";
private const string ValueKey = "value";
private const string GroupsPattern
= @"(?<selector>(?:(?:[^,{]+)\s*,?\s*)+)\{(?:(?<name>[^}:]+)\s*:\s*(?<value>[^};]+);?\s*)*\}";
private const string CommentsPattern
= @"(?<!"")\/\*.+?\*\/(?!"")";
private readonly Regex _pattern
= new Regex(GroupsPattern, RegexOptions.IgnoreCase | RegexOptions.Multiline);
public CSSParser(string cssString)
{
var noCommentsString = Regex.Replace(cssString, CommentsPattern, "");
var matches = _pattern.Matches(noCommentsString);
foreach (Match item in matches)
{
var selector = item.Groups[SelectorKey].Captures[0].Value.Trim();
var selectorParts = selector.Split(',').Select(s=>s.Trim());
foreach(var part in selectorParts)
{
if (!_dict.ContainsKey(part))
_dict[part] = new Dictionary<string, string>();
}
var classNameCaptures = item.Groups[NameKey].Captures;
var valueCaptures = item.Groups[ValueKey].Captures;
var count = item.Groups[NameKey].Captures.Count;
for (var i = 0; i < count; i++)
{
var className = classNameCaptures[i].Value.TrimIfNotNull();
var value = valueCaptures[i].Value.TrimIfNotNull();
foreach(var part in selectorParts)
{
_dict[part][className] = value;
}
}
}
}
public IEnumerable<KeyValuePair<string,string>> LookupValues(string selector)
{
IEnumerable<KeyValuePair<string,string>> result
= new KeyValuePair<string,string>[]{};
if (_dict.ContainsKey(selector))
{
var subdict = _dict[selector];
result = subdict.ToList();
}
return result;
}
public string LookupValue(string selector, string style)
{
string result = null;
if (_dict.ContainsKey(selector))
{
var subdict = _dict[selector];
if (subdict.ContainsKey(style))
result = subdict[style];
}
return result;
}
}
}
und es funktioniert gut mit Eingabe wie folgt aus:
[TestMethod]
public void TestParseMultipleElementNames()
{
const string css = @"h1, h2, h3, h4, h5, h6
{
font-family: Georgia, 'Times New Roman', serif;
color: #006633;
line-height: 1.2em;
font-weight: normal;
}
";
var parser = new CSSParser(css);
Assert.AreEqual("normal", parser.LookupValue("h4", "font-weight"));
}
aber wenn ich laufe es mit einem CSS-String keine Attribute enthält:
Das Programm hängt an dieser Zeile in CSSParser:
Der Debugger stoppt die Markierung der aktuell ausgeführten Zeile, der Schleifenblock selbst wird nie erreicht.
Warum hängt die MatchCollection mein Programm?
Der Vollständigkeit halber:
namespace Helpers.Extensions
{
public static class StringExtension
{
public static string TrimIfNotNull(this string input)
{
return input != null ? input.Trim() : null;
}
}
}
Ich bin kein Experte mit Regex, aber die Regex-Engine kann steckenbleiben oder eine lange Zeit dauern, wenn sie konstante Lookahead- und Lookbehind-Operationen durchführen muss. Entwerfen Sie Ihre Regex, um diese zu minimieren, würde helfen. Vielleicht kann ein Regex-Experte Ihnen bei den Einzelheiten helfen. +1 =] – Sean
Pausieren Sie den Debugger und schauen Sie sich den Stack an, um festzustellen, was passiert.Aktivieren Sie "Zeige externen Code", um alles zu sehen. – usr
a) Sprachen wie diese sollten nicht wirklich mit Regex geparst werden. b) Warum nicht [etwas von der Stange benutzen] (http://stackoverflow.com/q/512720/50776)? Es wird wahrscheinlich viel schneller und robuster sein und Sie in Ihrem Projekt mehr voranbringen, als es von Hand zu tun. – casperOne