2008-12-10 3 views
20

Я ищу выражение регулярного выражения, которое позволит мне извлечь содержимое HTML только из тегов тела из документа XHTML.Регулярное выражение для извлечения содержимого тела HTML

XHTML, который мне нужен для синтаксического анализа, будет очень простым файлом, мне не нужно беспокоиться о содержании JavaScript или <![CDATA[ тегах, например.

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

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
    <title> 
    </title> 
    </head> 
    <body contenteditable="true"> 
    <p> 
     Example paragraph content 
    </p> 
    <p> 
     &nbsp; 
    </p> 
    <p> 
     <br /> 
     &nbsp; 
    </p> 
    <h1>Header 1</h1> 
    </body> 
</html> 

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

((.|\n)*<body (.)*>)|((</body>(*|\n)*) 

... будет делать трюк, но это, кажется, не работает вообще с моим содержанием испытания в RegexBuddy.

+0

`Split()` является неправильным инструментом для этой работы. Просто используйте `Regex.Match (subject," (? S) ] *> (. *) "). Группы [1] .Value`. – 2016-09-14 05:47:10

ответ

23

Будет ли это работать?

((?:.(?!<body[^>]*>))+.<body[^>]*>)|(</body\>.+) 

Конечно, вам нужно добавить необходимые \s для того, чтобы принять во внимание < body ...> (элемент с пробелами), как в:

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

(.*<\s*body[^>]*>)|(<\s*/\s*body\s*\>.+) 
9

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

EDIT: В ответ на комментарий здесь; что парсер XML слишком медленный.

Существует два вида анализатора XML, один из которых называется DOM, большой и тяжелый, легкий и дружелюбный, он создает дерево из документа, прежде чем вы сможете что-либо сделать. Другой называется SAX и работает быстро и легко и работает, он читает файл последовательно. Вы хотите, чтобы SAX обнаружил тег Body.

Метод DOM хорош для многократного использования, вытягивания тегов и поиска того, кто является ребенком. Анализатор SAX считывает файл по порядку и быстро получает информацию, которую вы используете. Регулярное выражение не будет быстрее, чем синтаксический анализатор SAX, потому что они оба просто идут по совпадению файлов и шаблонов, за исключением того, что регулярное выражение не перестает смотреть на то, что оно обнаружило тег body, поскольку регулярное выражение не имеет встроенного знание XML. Фактически, ваш SAX-анализатор, вероятно, использует небольшие кусочки регулярного выражения для поиска каждого тега.

+4

Нет причин повторно изобретать колесо. Если это XHTML, это XML, а синтаксический анализатор XML - это инструмент для работы. +1 – 2008-12-10 15:09:59

+0

Это было первое решение, которое я устал, но, похоже, он работал довольно медленно. Я решил, что RegEx будет быстрее. – 2008-12-10 15:13:18

+1

Существует два вида анализатора XML, один из которых называется DOM, большой и тяжелый, легкий и дружелюбный, он создает дерево из документа, прежде чем вы сможете что-либо сделать. Другой называется SAX и работает быстро и легко и работает, он читает файл последовательно. Вы хотите, чтобы SAX обнаружил тег Body. – Karl 2008-12-10 15:19:48

3

Почему вы не можете просто разделить его на

</{0,1}body[^>]*> 

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

5
String toMatch="aaaaaaaaaaabcxx sldjfkvnlkfd <body>i m avinash</body>"; 
Pattern pattern=Pattern.compile(".*?<body.*?>(.*?)</body>.*?"); 
Matcher matcher=pattern.matcher(toMatch); 
if(matcher.matches()) { 
    System.out.println(matcher.group(1)); 
} 
1

Матч первого тег тела: <\s*body.*?>

матча последнего тела тег: <\s*/\s*body.*?>

(примечание: мы объясняем пространство в середине тегов, которая полностью действует наценка кстати)

Объедините их вместе, и вы получите все между ними, включая теги тела: <\s*body.*?>.*?<\s*/\s*body.*?>. И убедитесь, что вы используете режим Singleline, который будет игнорировать разрывы строк.

Это работает в VB.NET, и, надеюсь, и другие!

Смежные вопросы