在降价代码块之外查找图像标签

时间:2018-07-21 01:34:22

标签: python regex python-3.x bash markdown

简介

我有数百个带有代码块的markdown文件,它们看起来像这样。

```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>
  ```

我的目标是找到所有代码,而没有一个alt标签,在代码块之外。 < / p>

由于代码块的原因,不确定是否可以使用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标记

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

但是我觉得这可能是一种更清洁的方法

  1. 过滤掉每个代码块
  2. 找到每个img标签
  3. 找到所有没有alt标签的img标签

我在第一步上有些卡住。我可以使用此正则表达式找到每个代码块:

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

但是,我不确定如何将其反转,例如,找到它之外的所有文本。我会接受任何可以在bash脚本或python中运行的解决方案。

2 个答案:

答案 0 :(得分:0)

您绝对正确,这是正则表达式垃圾桶方法的经典案例:我们*跳过整体比赛中要避免的事情,并使用捕获组来获取我们实际想要的内容,即$HOME/.gitconfig

What_I_want_to_avoid|(What_I_want_to_match)

这里的想法是完全忽略正则表达式引擎返回的总体匹配:那就是垃圾箱。取而代之的是,我们只需要检查捕获组$ 1,该捕获组在设置后将包含img标签。

Demo

没有alt属性的匹配img标签的模式是borrowed hereherehere描述了垃圾桶方法。

Sample Code

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

实际上,只需将single backtick pair放在完整比赛中就足够了。但是,它可以说更具可读性,并且可以更清晰地演示该想法。

答案 1 :(得分:0)

我的方法是删除"`"之间的所有字符串,然后将文本提供给BeautifulSoup进行解析(我将找到所有没有img属性的alt标签,并将其打印为{{ 1}}):

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'])