正则表达式排除所有带有负前瞻匹配的组

时间:2019-09-27 17:59:32

标签: html regex regex-lookarounds regex-group

我有一个正则表达式可以从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 :(得分:1)

正则表达式为(?<=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文件系统中的合法文件名。

您甚至可以在不使用先行搜索或先行搜索的情况下完成任务:

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