Regex для сопоставления атрибутов в HTML? - PullRequest
1 голос
/ 21 января 2009

У меня есть текстовый файл, который на самом деле является источником HTML некоторой веб-страницы. Внутри этого txt-файла есть различные строки, перед которыми стоит тег "title =". например

<div id='UWTDivDomains_5_6_2_2'  title='Connectivity Framework'> 

Я заинтересован в том, чтобы текст Connectivity Framework был извлечен и записан в отдельный файл.

Подобно этому, есть много таких тегов, каждый из которых имеет свой текст после заголовка = "некоторый текст, который мне нужно извлечь" Я хочу извлечь все такие экземпляры текста из исходного файла HTML / TXT и записать в отдельный файл TXT. Текст может содержать только строчные буквы, прописные буквы и цифры. Длина каждой текстовой строки (в символах) будет варьироваться.

Я использую PowerGrep для Windows. Powergrep позволяет мне искать текстовый файл с регулярным выражением inout. Я пытался использовать поиск как название = '[A-Za-Z0-9]

Показывает правильные совпадения, но соответствует только первому символу строки и записывает только первый символ текстовой строки, сопоставленной со вторым txt-файлом, а не всю строку.

Я хочу, чтобы все строки были сопоставлены и записаны во второй файл.

Какое правильное регулярное выражение или способ сделать то, что я хочу сделать, используя powergrep?

-AD.

Ответы [ 6 ]

6 голосов
/ 21 января 2009

Я просто не уверен, сколько раз нужно было задавать вопрос парсинга регулярных выражений HTML-файлов (и отвечал правильным решением "использовать парсер DOM"). Это приходит каждый день.

Трудности:

  • В HTML атрибуты могут иметь одинарные кавычки, двойные кавычки или даже без кавычек;
  • Подобные строки могут появляться в самом документе HTML;
  • Вы должны справиться с правильным побегом; и
  • Искаженный HTML (приличные парсеры чрезвычайно устойчивы к распространенным ошибкам).

Так что, если вы учитываете все это (и это становится довольно сложным, но все еще несовершенным регулярным выражением), это все равно не 100%.

HTML-парсеры существуют по причине. Используйте их.

3 голосов
/ 21 января 2009

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

Квадратные скобки указывают класс символов - это означает, что регулярное выражение будет соответствовать любому символу в этих скобках. Однако, как и все остальное, он будет соответствовать ему только один раз по умолчанию. Так же как регулярное выражение "s" будет соответствовать только первому символу в "ssss", регулярное выражение "[a-zA-Z0-9]" будет соответствовать только первому символу в "Connectivity Framework".

Добавляя повторение , можно получить этот класс символов для многократного соответствия. Самый простой способ сделать это - добавить звездочку после нее (которая будет соответствовать 0 или более вхождениям). Таким образом, регулярное выражение "[a-zA-Z0-9]*" будет соответствовать столько символов в строке, пока не попадет на символ, который не входит в этот класс символов (в вашем случае это пробел, поскольку вы не включили его в скобки).

Регулярные выражения могут быть довольно сложными для точного описания синтаксиса - что если кто-то вставит в атрибут не алфавитно-цифровой символ, например амперсанд? Вы можете попытаться захватить весь ввод между кавычками, сделав набор символов «что угодно, кроме символа кавычки», поэтому «'[^']*'» обычно делает правильные вещи. Зачастую вам также нужно помнить о побеге (например, с помощью строки 'Mary\'s lamb' вы действительно хотите захватить апостроф в середине, чтобы простой набор символов «все, кроме апострофов» его не разрезал), хотя, к счастью, это не так проблема с XML / HTML в соответствии со спецификациями.

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

2 голосов
/ 21 января 2009

Я не знаком с PowerGrep, однако ваше регулярное выражение неполное. Попробуйте это:

title='[a-zA-Z0-9 ]*'

или еще лучше:

title='([^']*)'
1 голос
/ 21 января 2009

Я бы использовал это регулярное выражение, чтобы получить значения атрибута title

<[a-z]+[^>]*\s+title\s*=\s*("[^"]*"|'[^']*'|[^\s >]*)

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

0 голосов
/ 21 января 2009

Попробуйте вместо этого:

title=\'[a-zA-Z0-9]*\'
0 голосов
/ 21 января 2009

Вот необходимое вам регулярное выражение

title='([a-zA-Z0-9]+)'

но если вы собираетесь делать намного больше подобных вещей, использование парсера может сделать его более надежным и полезным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...