Извлечение текстовых полей из тегов в HTML-сообщении


Что я делаю

У меня есть строка с HTML такой информации:

<p> <span class="fieldText" fieldId="field-4">Some text</span> this is a test</p>

Моя цель метода-создать словарь с этого значения:

**key**     **value**
field-4    Some text

Это код, который я использую, чтобы выполнить мою задачу:

public static Dictionary<int,String> getFields(String mensaje) 
    {
        Dictionary<int,String> fields = new Dictionary<int,string>();
        Match m = Regex.Match(mensaje, @"^(.*?<span .*?>(.*?)</span>.*?)+$", RegexOptions.Singleline);
        for (int i = 0; i < m.Groups[2].Captures.Count; i++)
        {
            String value = m.Groups[1].Captures[i].Value;
            Match m2 = Regex.Match(value, "^(.*?fieldId=.*?\"(.*?)\">.*?)+$", RegexOptions.Singleline);
            String fieldId = m2.Groups[2].Captures[0].Value;
            fieldId = fieldId.Replace("field-", String.Empty);
            fields.Add(int.Parse(fieldId),m.Groups[2].Captures[i].Value);
        }

        return fields;
    }

Как я могу улучшить мой код?



3341
4
задан 19 июля 2011 в 08:07 Источник Поделиться
Комментарии
1 ответ

Я знаю, что это ревью кода не переписывать мой код, но я хотел бы предложить, используя сторонний анализатор html (как в HTML ловкость обновления например) за регулярные выражения, если это вариант.

Я понимаю, что ты делаешь очень тривиальный парсинг здесь, но из моего личного опыта регулярных выражений расти к unmaintainable статус быстрее, чем что-нибудь в разработке программного обеспечения.

Если вы должны использовать парсер HTML, вы могли бы сделать что-то вроде этого:

string htmlToParse = "<p><span class=\"fieldText\" fieldId=\"field-4\">Some text</span> this is a test</p><p><span class=\"fieldText\" fieldId=\"field-5\">Some more text</span> this is another test</p>";
const string ElementToParse = "span";
const string IdField = "FieldId";

HtmlDocument htmlDocument = new HtmlDocument();
htmlDocument.LoadHtml(htmlToParse);

int fieldId = default( int );

Dictionary<int,string> fieldValuesTable =
(
from
htmlNode in htmlDocument.DocumentNode.DescendantNodes()
where
htmlNode.Name.Equals( ElementToParse, StringComparison.InvariantCultureIgnoreCase )
&&
htmlNode.Attributes.Contains( IdField )
let
id = htmlNode.Attributes[ IdField ].Value
where
Int32.TryParse( id.Substring( id.IndexOf( "-" ) + 1 ), out fieldId ) // this is stil not ideal,
select
new { Id = fieldId, Text = htmlNode.InnerText }
).ToDictionary( f => f.Id, f => f.Text );

Вы получаете на выходе:

4 : Some text
5 : Some more text

ИМХО, это намного чище и ремонтопригодны.

8
ответ дан 20 июля 2011 в 02:07 Источник Поделиться