Нужна помощь в изменении регулярного выражения - PullRequest
0 голосов
/ 22 августа 2010

На днях я стану хорошим в регулярных выражениях, но сейчас ...

Я анализирую HTML-страницу в поисках файлов MP3, используя следующее выражение (которое работает):

"<A HREF=\"([^\"]+)\"[^>]*>([^<]+?)\\.mp3</A>"

Теперь я хочу найти файлы MP3 и OGG.Похоже на простую модификацию OR (.mp3 || .ogg), но я не совсем уверен, как я это поместил?См. Попытка разобрать ссылки в списке каталогов HTML с помощью Java regex для получения дополнительной информации.

Ответы [ 2 ]

5 голосов
/ 22 августа 2010

Понимание шаблона

У вас есть следующий строковый литерал Java:

// Java string literal
"<A HREF=\"([^\"]+)\"[^>]*>([^<]+?)\\.mp3</A>"

Шаблон, представленный этой строкой при обработке всех escape-последовательностей, таков:

// the regex pattern
<A HREF="([^"]+)"[^>]*>([^<]+?)\.mp3</A>

Теперь давайте разберем этот шаблон на части:

_________       _     _        E________
<A HREF="([^"]+)"[^>]*>([^<]+?)\.mp3</A>
         \_____/       \______/
            1              2

Итак, части этого регулярного выражения:

  1. <A HREF=" в буквальном соответствии
  2. ([^"]+), т. Е. Все, кроме двойных кавычек, захваченных в группе 1
  3. ", сопоставленных буквально
  4. [^>]*, т. Е. Все, кроме >
  5. >, сопоставленных буквально
  6. ([^<]+?), т. Е. Все, кроме <, как можно меньше, захваченных в группе 2
  7. .mp3</A>, сопоставленных буквально (. экранируется обратной косой чертой)

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

  • Значение атрибута href соответствует части 2;он должен быть заключен в двойные кавычки и сам по себе не может содержать никаких двойных кавычек.Это совпадение фиксируется в группе 1.
  • Все оставшиеся атрибуты соответствуют части 4. href должен быть первым атрибутом, иначе регулярное выражение не будет совпадать.
  • Часть 6соответствует имени файла, захватывая в группу 2.
  • Часть 7 соответствует расширению и сразу после закрывающего элемента.Нежелание части 6, вероятно, не является необходимым.

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


Изменение шаблона

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

  • this|that соответствует одной из этих двух строк:
    • "this"
    • "that"
  • this|that thing соответствует одной из следующих двух строк:
    • "this"
    • "that thing"
  • (this|that) thing соответствует одной из этих двух строк:
    • "this thing"
    • "that thing"
  • (this|that) (thing|stuff) соответствует одной из этихчетыре строки:
    • "this thing"
    • "that thing"
    • "this stuff"
    • "that stuff"

Таким образом, чтобы разрешить расширение mp3 и ogg, мы можем изменить mp3 в шаблоне на (mp3|ogg).Обратите внимание, что эта группа будет сопоставлять и захватывать расширение в группу 3.

Таким образом, последний шаблон:

<A HREF="([^"]+)"[^>]*>([^<]+)\.(mp3|ogg)</A>
         \_____/       \_____/  \_______/
          1:url      2:filename   3:ext

В качестве строкового литерала Java это:

"<A HREF=\"([^\"]+)\"[^>]*>([^<]+)\\.(mp3|ogg)</A>"

Приложение

[…] представляет собой класс символов .Нечто вроде [aeiou] соответствует одному из строчных гласных.[^…] является отрицательным классом символов.[^aeiou] соответствует одному из , кроме строчных гласных.

(…) - это группа захвата .Позволяет получить строку, с которой он совпал, для последующего извлечения.

* и + являются спецификаторами повторения .По умолчанию повторение является жадным (то есть соответствует много , насколько это возможно).? в +? делает его неохотным (то есть соответствует нескольким , насколько это возможно).

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

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

Обратите внимание, что шаблон регулярного выражения по умолчанию чувствителен к регистру.В Java вы можете использовать флаг Pattern.CASE_INSENSITIVE (встраиваемый в шаблон как (?i)).

4 голосов
/ 22 августа 2010
Replace 
    \.mp3
with
    \.((mp3)|(ogg))

И остерегайтесь парсинга HTML с помощью регулярных выражений.

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