贪婪的正则表达式向后看[重复]

Posted

技术标签:

【中文标题】贪婪的正则表达式向后看[重复]【英文标题】:Greedy regex lookbehind [duplicate] 【发布时间】:2020-01-11 17:36:18 【问题描述】:

我正在编写一个正则表达式来获取"" 之间的数据。我遇到的唯一问题是最后一个" 被捕获。 Regex

  line = '<DT><A HREF="https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html" ADD_DATE="1567455957">Clickjacking Defense · OWASP Cheat Sheet Series</A>'
  capture_regex = re.compile(r'(?<=HREF=").*?"',re.IGNORECASE)
  m = capture_regex.search(line)

m.group() 打印出https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html"。如何编写不包含最后一个引号的正则表达式。

回答了我的问题。我补充说我在我的正则表达式中添加了所谓的非贪婪。 capture_regex = re.compile(r'(?&lt;=HREF=").*?(?=")',re.IGNORECASE)。通过在* 之后添加? 使其仅在第一个" 处停止。

【问题讨论】:

使用前瞻(?=") 而不仅仅是" 您应该避免使用正则表达式来解析 HTML 文件。应该改用bs4 (?=") 查找最后一个 "bs4 会起作用,我正在努力提高我的正则表达式技能。 【参考方案1】:
capture_regex = re.compile(r'(?<=HREF=").*?(?=")',re.IGNORECASE)

working fiddle

编辑:调整正则表达式,因为它太贪婪了。感谢@newdeveloper 指出!

【讨论】:

这捕获了比需要更多的数据。 https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html" ADD_DATE="1567455957 @newdeveloper:我多么愚蠢地错过了这一点。现在已更正... 是的,我明白了,谢谢。【参考方案2】:

也许,来自 bs4 的 find_all 可能工作正常:

from bs4 import BeautifulSoup

line = '<DT><A HREF="https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html" ADD_DATE="1567455957">Clickjacking Defense · OWASP Cheat Sheet Series</A>'
soup = BeautifulSoup(line, 'html.parser')

for l in soup.find_all('a', href=True):
    print(l['href'])

输出

https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html

如果不是,也许,一些类似于

的表达
(?i)href="\s*([^\s"]*?)\s*"

re.findall 可能在这里工作:

import re

expression = r'(?i)href="\s*([^\s"]*?)\s*"'

string = """
<DT><A HREF="https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html" ADD_DATE="1567455957">Clickjacking Defense · OWASP Cheat Sheet Series</A>
<DT><A HREF=" https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html " ADD_DATE="1567455957">Clickjacking Defense · OWASP Cheat Sheet Series</A>
"""

print(re.findall(expression, string))

输出

['https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html', 'https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html']

如果您想探索/简化/修改表达式,它已经 在右上角的面板上进行了解释 regex101.com。如果你愿意,你 也可以在this link看,怎么搭配 针对一些样本输入。


【讨论】:

【参考方案3】:

这将起作用:

import re

line = '<DT><A HREF="https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html" ADD_DATE="1567455957">Clickjacking Defense · OWASP Cheat Sheet Series</A>'

capture_regex = re.compile(r'(?<=HREF=")([^"]*)(?:")',re.IGNORECASE)
# capture_regex = re.compile(r'(?:HREF=")([^"]*)(?:")',re.IGNORECASE) this will work too
print(capture_regex.search(line).groups())
# print(capture_regex.findall(line))  # if your text contains more than one HREF

输出:

  ['https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html']

【讨论】:

以上是关于贪婪的正则表达式向后看[重复]的主要内容,如果未能解决你的问题,请参考以下文章

15.python正则匹配 元字符转义重复或捕获分组断言:零度断言负向零宽断言贪婪非贪婪引擎选项

第11.9节 Python正则表达式的贪婪模式和非贪婪模式

积极的向后看没有按预期工作

正则表达式?非贪婪匹配

正则表达式?非贪婪匹配

JavaScript正则表达式,这一篇足矣