2016-01-27 4 views
0

Я анализирую несколько документов HTML и каждый из них должен попытаться извлечь почтовый адрес в Великобритании. Для того, чтобы сделать это я разбор HTML с AngleSharp, а затем ищу узлы с TextContent, которые соответствуют моему RegEx:Найти узел HTML/XML с помощью RegEx

var parser = new HtmlParser(); 
var source = "<html><head><title>Test Title</title></head><body><h1>Some example source</h1><p>This is a paragraph element and example postode EC1A 4NP</body></html>"; 
var document = parser.Parse(source); 
Regex searchTerm = new Regex("([A-PR-UWYZ][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)"); 
var list = document.All.Where(m => searchTerm.IsMatch((m.TextContent ?? "").ToUpper())); 

Это возвращает 3 результатов, html, body и p элементов. Единственный элемент, который я хочу вернуть, - это элемент p, поскольку он правильно соответствует правилу innerText. Также может быть несколько совпадений на странице, поэтому я не могу просто вернуть последний результат. Я хочу просто вернуть любые элементы, в которых текст в этом элементе (а не в любых дочерних узлах) соответствует регулярному выражению.

Редактировать

я не знаю заранее структуру DOC или даже тег, почтовый индекс будет в который почему я использую регулярное выражение. Как только у меня есть результат, я планирую пройти через dom, чтобы получить остальную часть адреса, поэтому я не просто хочу обрабатывать документ как строку

+0

Знаете ли вы заранее, что это будет «P», или вам нужен какой-либо узел с текстовым контентом, который содержит вашу информацию (только для образца «P» страница https://github.com/AngleSharp/AngleSharp/wiki/Examples предоставляет достаточно информации). –

+0

Я не знаю, какой тег адрес будет содержать внутри - это могут быть P, DIV, DD и т. Д. – Macros

ответ

0

Хорошо, я взял другой подход, в конце концов. Я искал HTML-документ как строку с помощью RegEx NOT для анализа HTML-кода, но просто для того, чтобы найти точное значение соответствия. как только я получил это значение, было достаточно просто использовать выражение xpath для возврата узла. В приведенном выше примере, поиск регулярного выражения возвращает EC1A 4NP и следующий XPATH:

//*[contains(text(),'EC1A 4NP')] 

возвращает нужный узел. Для простоты XPath я переключился с AngleSharp на HtmlAgilityPack для разбора HTML

0

Если вы хотите извлечь конкретный узел в хорошо известном адресе, образованный HTML/XML-документ, посмотрите на использование XPath. Здесь есть несколько примеров: MSDN

Вы можете использовать библиотеки утилит, такие как HTML Tidy, для «очистки» html и сделать его хорошо сформированным, если его еще нет.

+0

Абсолютно не связан с вопросом - OP уже использует HtmlParser для чтения HTML - он будет иметь точно такую ​​же проблему с любым парсером который создает дерево. –

+0

Из фрагмента показано, что он запускает регулярное выражение по всему документу. Использование XPath приведет их прямо к элементу, который содержит адрес, который им нужно проанализировать. –

+0

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

0

Я быстро посмотрел на doco парсера. Ниже приведено то, что вам нужно сделать, если вы хотите проверить только текст в тегах <p>.

var list = document.All.Where(m => m.LocalName.ToUpper() == "P" && searchTerm.IsMatch((m.TextContent ?? "").ToUpper()));

+0

Я не знаю, какой тег адрес будет содержаться внутри - он мог бы быть P, DIV, DD и т. д. – Macros