Извлечение всего, кроме тегов из веб-страницы без анализатора - с помощью сканера и регулярных выражений? - PullRequest
0 голосов
/ 07 сентября 2010

Работа над Android SDK - это Java, но не все.

У меня есть решение, которое извлекает два шаблона регулярных выражений из веб-страниц. Проблемы у меня в том, что он находит вещи внутри тегов HTML. Я попробовал jTidy, но это было слишком медленно на Android. Не знаю, почему, но мое решение для сопоставления регулярных выражений в Сканере взбивает его много раз.

В настоящее время я беру источник страницы в IntputStream

is = uconn.getInputStream();

и сопоставить и извлечь, как это:

Scanner scanner = new Scanner(in, "UTF-8");
String match = "";   
while (match != null) {   
    match = scanner.findWithinHorizon(extractPattern, 0);   
    if (match != null) {   
        String matchit = scanner.match().group(grp);  

это работает очень хорошо и быстро.

Мой шаблон регулярных выражений уже довольно сумасшедший, на самом деле два шаблона в или вроде этого (p1 | p2)

Есть идеи, как мне это сделать ", но не внутри тегов HTML" или исключить теги HTML в начале? Если я могу исключить теги HTML из моего источника, это, вероятно, значительно ускорит мой интерфейс, поскольку у меня есть несколько других вещей, которые мне нужно сделать с необработанными данными.

Ответы [ 2 ]

1 голос
/ 07 сентября 2010

Одна вещь, которую вы можете сделать, это добавить заглядывание к закрывающей угловой скобке:

(p1|p2)(?![^<>]*+>)

Идея в том, что после того, как вы найдете совпадение, вы немного отсканируете вперед; если вы нашли закрывающую скобку, не увидев сначала открывающую скобку, совпадение должно быть внутри тега, поэтому отклоните его. Но имейте в виду, что даже в правильно сформированном HTML есть много вещей, которые могут вас испортить, например комментарии SGML, разделы CDATA или даже угловые скобки в значениях атрибутов.

Другой подход заключается в сопоставлении тегов и игнорировании этих совпадений:

((?:<[^<>]++>)++)(p1|p2)

Затем вы проверяете, соответствовала ли группа № 1:

MatchResult match = scanner.match();
if (match.start(1) != -1) {
    // keep searching
}

Но опять же, как общее решение , оно слишком хрупкое по причинам, которые я привел выше. Вам следует использовать только одно из этих решений (или любое решение для регулярных выражений), если вы уверены, что оно совместимо с конкретными страницами, над которыми вы работаете.

1 голос
/ 07 сентября 2010

Почему бы вам не использовать javax.xml.parsers для анализа HTML (ergo xml)

...