Регулярное выражение, исключающее все группы, совпадающие с отрицательным прогнозом - PullRequest
0 голосов
/ 27 сентября 2019

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

Мое текущее регулярное выражение: /href="([\w]+)(\.[\w]+)*/ig

  1. Соответствует первой группе: 1+ символов слова
  2. Соответствует второй группе 0+ раз: . затем 1+ символов слова
  3. Флаги: совпадают с учетом регистра и максимально возможным числом

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


Из чтения по всему Интернету:

Для пересчета:

  • У меня есть две группы.
  • То, что я должен сделать, это использовать отрицательный прогноз для соответствия .ini, а затем, если он совпадает, исключить все групп из этого совпадения.

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


Пример строки ввода

Пример блока кода HTML, с которым я проверяю регулярное выражение.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
 <head>
  <title>Index of /images/AAVS</title>
 </head>
 <body>
<h1>Index of /images/AAVS</h1>
  <table>
   <tr><th valign="top"><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr>
   <tr><th colspan="5"><hr></th></tr>
<tr><td valign="top"><img src="/icons/back.gif" alt="[PARENTDIR]"></td><td><a href="/images/">Parent Directory</a>       </td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="20190823/">20190823/</a>              </td><td align="right">2019-09-19 19:37  </td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="20190826/">20190826/</a>              </td><td align="right">2019-09-19 19:31  </td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="desktop.ini">desktop.ini</a>            </td><td align="right">2019-09-19 19:24  </td><td align="right">136 </td><td>&nbsp;</td></tr>
   <tr><th colspan="5"><hr></th></tr>
</table>
</body></html>

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

1 Ответ

0 голосов
/ 27 сентября 2019

Регулярное выражение: (?<=href=")[^"]+(?<!\.ini)(?=")

  1. (?<=href=") Позитивный взгляд за href="
  2. [^"]+ Соответствует какмного символов не двойных кавычек, как вы можете
  3. (?<!\.ini) Отрицательный взгляд за .ini
  4. (?=") Позитивный взгляд двойногоцитата

Код:

import re

html = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
 <head>
  <title>Index of /images/AAVS</title>
 </head>
 <body>
<h1>Index of /images/AAVS</h1>
  <table>
   <tr><th valign="top"><img src="/icons/blank.gif" alt="[ICO]"></th><th><a href="?C=N;O=D">Name</a></th><th><a href="?C=M;O=A">Last modified</a></th><th><a href="?C=S;O=A">Size</a></th><th><a href="?C=D;O=A">Description</a></th></tr>
   <tr><th colspan="5"><hr></th></tr>
<tr><td valign="top"><img src="/icons/back.gif" alt="[PARENTDIR]"></td><td><a href="/images/">Parent Directory</a>       </td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="20190823/">20190823/</a>              </td><td align="right">2019-09-19 19:37  </td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/icons/folder.gif" alt="[DIR]"></td><td><a href="20190826/">20190826/</a>              </td><td align="right">2019-09-19 19:31  </td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="/icons/unknown.gif" alt="[   ]"></td><td><a href="desktop.ini">desktop.ini</a>            </td><td align="right">2019-09-19 19:24  </td><td align="right">136 </td><td>&nbsp;</td></tr>
   <tr><th colspan="5"><hr></th></tr>
</table>
</body></html>"""

l = re.findall(r'(?<=href=")[^"]+(?<!\.ini)(?=")', html, flags=re.I)
print(l)

Печать:

['?C=N;O=D', '?C=M;O=A', '?C=S;O=A', '?C=D;O=A', '/images/', '20190823/', '20190826/']

Приведенное выше регулярное выражение будет принимать любое значение href, и поэтому оно возвращает значениятакие как '?C=N;O=D'.Если вы хотите ограничить его значениями, которые составляют имена файлов и папок, которые вы специально ищете, вы можете использовать более ограничительное регулярное выражение, например:

(?<=href=")[a-z0-9_./-]+(?<!\.ini)(?=")

Это приведет к печати:

['/images/', '20190823/', '20190826/']

Но, на самом деле, исходя из моих исследований, ?C=N;O=D будет допустимым именем файла в файловой системе Linux.

Вы даже можете выполнить задачу, не используя lookbehind или lookahead:

l = [m.group(1) for m in re.finditer(r'(?:href=")([^"]+)(?:")', html, flags=re.I) if not m.group(1).lower().endswith(".ini")]
...