Поиск тегов изображения вне блоков кода уценки

1

вступление

У меня есть несколько сотен файлов разметки с блоками кода в них, и они выглядят примерно так.

'''html
<img src="fil.png">
'''

- [ ] Here is another image <img src="fil.png"> and another '<img src="fil.png">'

  '''html
  <a href="scratch/index.html" id="scratch" data-original-title="" title="" aria-describedby="popover162945">
    <div class="logo-wrapper">
    </div>
    <div class="name">
      <span>Scratch</span>
    </div>
    <img src="fil.png">
  </a>
  '''

Моя цель - найти все теги IMG без тега alt вне блоков кода.

Не уверен, могу ли я использовать HTML: парсер либо из-за кодовых блоков...

Примеры

Я не ищу идеальное решение, просто что-то, что найдет простые теги img, охватывающие несколько строк.

'''html
<img src="fil.png">
'''

Не следует находить этот, так как он находится внутри блока img.

- [ ] Here is another image '<img src="fil.png">' and another <img src="dog.png" title: "re
aaaaaaaaaaaaaaaallllyl long title">

Нельзя найти первую (как она окружена), однако она должна найти вторую, даже если она охватывает несколько строк.

попытка

Я пробовал несколько разных методов, используя все: от bash и grep до python. Я могу получить теги img используя следующее regex

<img(\s*(?!alt)([\w\-])+=([\"\'])[^\"\']+\3)*\s*\/?>

Однако я считаю, что более чистым подходом может быть

  1. Отфильтровать каждый блок кода
  2. найти каждый тег img
  3. найти каждый тег img без метки alt

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

'''[a-z]*\n[\s\S]*?\n'''

Однако я не уверен, как инвертировать это, например, найти весь текст за его пределами. Я бы принял любые решения, которые можно запустить в сценарии bash или из python.

Теги:
python-3.x
markdown

2 ответа

0
Лучший ответ

Вы абсолютно правы, это классический случай для подхода regex trashcan: Мы * ПРОПУСКАЕМ, что следует избегать в общем матче, и использовать группу захвата для того, что мы действительно хотим, т.е. What_I_want_to_avoid|(What_I_want_to_match):

'''.*?'''|'.*?'|(<img(?!.*?alt=(['\"]).*?\2)[^>]*)(>)

Идея здесь состоит в том, чтобы полностью игнорировать общие совпадения, возвращаемые движком регулярных выражений: это мусорный ящик. Вместо этого нам нужно только проверить группу захвата $ 1, которая, когда установлена, содержит img-теги.

демонстрация

Здесь заимствован шаблон для соответствия img-тегам без атрибута alt. Метод trashcan описан здесь и здесь.

Образец кода:

import re
regex = r"'''.*?'''|'.*?'|(<img(?!.*?alt=(['\"]).*?\2)[^>]*)(>)"
test_str = ("'''html\n"
    "<img src=\"fil.png\">\n"
    "'''\n\n"
    "- [ ] Here is another image <img src=\"fil.png\"> and another '<img src=\"fil.png\">'\n\n"
    "  '''html\n"
    "  <a href=\"scratch/index.html\" id=\"scratch\" data-original-title=\"\" title=\"\" aria-describedby=\"popover162945\">\n"
    "    <div class=\"logo-wrapper\">\n"
    "    </div>\n"
    "    <div class=\"name\">\n"
    "      <span>Scratch</span>\n"
    "    </div>\n"
    "    <img src=\"fil.png\">\n"
    "  </a>\n"
    "  '''")

matches = re.finditer(regex, test_str, re.DOTALL)
for match in matches:
    if match.group(1):
        print ("Found at {start}-{end}: {group}".format(start = match.start(1), end = match.end(1), group = match.group(1)))

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

  • 0
    @ ØisteinSøvik Как быстро прослеживание, здесь оптимизированная версия шаблона с помощью отрицания группы символов и притяжательных кванторов группы: `` + [^ ]++ + | ... ` , чтобы использовать его необходимо использовать альтернативный пакет регулярных выражений для Python: импорт регулярных выражений как ре
0

Мой подход заключается в удалении всех строк между "'", а затем просто отправьте текст в BeautifulSoup для синтаксического анализа (я найду все теги img без атрибута alt и распечатаю его src):

data = """
'''html
<img src="fil.png">
'''

- [ ] Here is another image <img src="fil.png"> and another '<img src="fil.png">'

  '''html
  <a href="scratch/index.html" id="scratch" data-original-title="" title="" aria-describedby="popover162945">
    <div class="logo-wrapper">
    </div>
    <div class="name">
      <span>Scratch</span>
    </div>
    <img src="fil.png">
  </a>
  '''
  """

import re
from bs4 import BeautifulSoup

soup = BeautifulSoup(re.sub(r''+[^']+'+', '', data), 'lxml')
for img in soup.find_all(lambda t: t.name == 'img' and not 'alt' in t.attrs):
    print(img['src'])

Выход:

fil.png

Ещё вопросы

Сообщество Overcoder
Наверх
Меню