使用 Python 从 Markdown 中提取 URL 和锚文本
Extracting URL and anchor text from Markdown using Python
我正在尝试从 Markdown 中提取锚文本和关联的 URL。我看过 this question. Unfortunately, the answer 似乎没有完全回答我想要的。
在Markdown中,有两种插入link的方法:
示例 1:
[anchor text](http://my.url)
示例 2:
[anchor text][2]
[1]: http://my.url
我的脚本看起来像这样(注意我使用的是 regex,不是 re):
import regex
body_markdown = "This is an [inline link](http://google.com). This is a [non inline link][4]\r\n\r\n [1]: http://yahoo.com"
rex = """(?|(?<txt>(?<url>(?:ht|f)tps?://\S+(?<=\P{P})))|\(([^)]+)\)\[(\g<url>)\])"""
pattern = regex.compile(rex)
matches = regex.findall(pattern, body_markdown, overlapped=True)
for m in matches:
print m
这会产生输出:
('http://google.com', 'http://google.com')
('http://yahoo.com', 'http://yahoo.com')
我的预期输出是:
('inline link', 'http://google.com')
('non inline link', 'http://yahoo.com')
如何从 Markdown 中正确捕获锚文本?
How can I properly capture the anchor text from Markdown?
将其解析为结构化格式(例如,html),然后使用适当的工具提取 link 个标签和地址。
import markdown
from lxml import etree
body_markdown = "This is an [inline link](http://google.com). This is a [non inline link][1]\r\n\r\n [1]: http://yahoo.com"
doc = etree.fromstring(markdown.markdown(body_markdown))
for link in doc.xpath('//a'):
print link.text, link.get('href')
这让我:
inline link http://google.com
non inline link http://yahoo.com
另一种方法是编写您自己的 Markdown 解析器,这似乎是您不应该集中精力的地方。
您可以使用几个简单的 re
模式来完成:
import re
INLINE_LINK_RE = re.compile(r'\[([^\]]+)\]\(([^)]+)\)')
FOOTNOTE_LINK_TEXT_RE = re.compile(r'\[([^\]]+)\]\[(\d+)\]')
FOOTNOTE_LINK_URL_RE = re.compile(r'\[(\d+)\]:\s+(\S+)')
def find_md_links(md):
""" Return dict of links in markdown """
links = dict(INLINE_LINK_RE.findall(md))
footnote_links = dict(FOOTNOTE_LINK_TEXT_RE.findall(md))
footnote_urls = dict(FOOTNOTE_LINK_URL_RE.findall(md))
for key, value in footnote_links.iteritems():
footnote_links[key] = footnote_urls[value]
links.update(footnote_links)
return links
然后你可以像这样使用它:
>>> body_markdown = """
... This is an [inline link](http://google.com).
... This is a [footnote link][1].
...
... [1]: http://yahoo.com
... """
>>> links = find_md_links(body_markdown)
>>> links
{'footnote link': 'http://yahoo.com', 'inline link': 'http://google.com'}
>>> links.values()
['http://yahoo.com', 'http://google.com']
将@mreinhardt 解决方案修改为 return 所有对的列表(而不是字典)(text, link)
:
import re
INLINE_LINK_RE = re.compile(r'\[([^\]]+)\]\(([^)]+)\)')
FOOTNOTE_LINK_TEXT_RE = re.compile(r'\[([^\]]+)\]\[(\d+)\]')
FOOTNOTE_LINK_URL_RE = re.compile(r'\[(\d+)\]:\s+(\S+)')
def find_md_links(md):
""" Return dict of links in markdown """
links = list(INLINE_LINK_RE.findall(md))
footnote_links = dict(FOOTNOTE_LINK_TEXT_RE.findall(md))
footnote_urls = dict(FOOTNOTE_LINK_URL_RE.findall(md))
for key in footnote_links.keys():
links.append((footnote_links[key], footnote_urls[footnote_links[key]]))
return links
我在 python3 中测试 链接为:
[h](http://google.com) and [h](https://goog.e.com)
我正在尝试从 Markdown 中提取锚文本和关联的 URL。我看过 this question. Unfortunately, the answer 似乎没有完全回答我想要的。
在Markdown中,有两种插入link的方法:
示例 1:
[anchor text](http://my.url)
示例 2:
[anchor text][2]
[1]: http://my.url
我的脚本看起来像这样(注意我使用的是 regex,不是 re):
import regex
body_markdown = "This is an [inline link](http://google.com). This is a [non inline link][4]\r\n\r\n [1]: http://yahoo.com"
rex = """(?|(?<txt>(?<url>(?:ht|f)tps?://\S+(?<=\P{P})))|\(([^)]+)\)\[(\g<url>)\])"""
pattern = regex.compile(rex)
matches = regex.findall(pattern, body_markdown, overlapped=True)
for m in matches:
print m
这会产生输出:
('http://google.com', 'http://google.com')
('http://yahoo.com', 'http://yahoo.com')
我的预期输出是:
('inline link', 'http://google.com')
('non inline link', 'http://yahoo.com')
如何从 Markdown 中正确捕获锚文本?
How can I properly capture the anchor text from Markdown?
将其解析为结构化格式(例如,html),然后使用适当的工具提取 link 个标签和地址。
import markdown
from lxml import etree
body_markdown = "This is an [inline link](http://google.com). This is a [non inline link][1]\r\n\r\n [1]: http://yahoo.com"
doc = etree.fromstring(markdown.markdown(body_markdown))
for link in doc.xpath('//a'):
print link.text, link.get('href')
这让我:
inline link http://google.com
non inline link http://yahoo.com
另一种方法是编写您自己的 Markdown 解析器,这似乎是您不应该集中精力的地方。
您可以使用几个简单的 re
模式来完成:
import re
INLINE_LINK_RE = re.compile(r'\[([^\]]+)\]\(([^)]+)\)')
FOOTNOTE_LINK_TEXT_RE = re.compile(r'\[([^\]]+)\]\[(\d+)\]')
FOOTNOTE_LINK_URL_RE = re.compile(r'\[(\d+)\]:\s+(\S+)')
def find_md_links(md):
""" Return dict of links in markdown """
links = dict(INLINE_LINK_RE.findall(md))
footnote_links = dict(FOOTNOTE_LINK_TEXT_RE.findall(md))
footnote_urls = dict(FOOTNOTE_LINK_URL_RE.findall(md))
for key, value in footnote_links.iteritems():
footnote_links[key] = footnote_urls[value]
links.update(footnote_links)
return links
然后你可以像这样使用它:
>>> body_markdown = """
... This is an [inline link](http://google.com).
... This is a [footnote link][1].
...
... [1]: http://yahoo.com
... """
>>> links = find_md_links(body_markdown)
>>> links
{'footnote link': 'http://yahoo.com', 'inline link': 'http://google.com'}
>>> links.values()
['http://yahoo.com', 'http://google.com']
将@mreinhardt 解决方案修改为 return 所有对的列表(而不是字典)(text, link)
:
import re
INLINE_LINK_RE = re.compile(r'\[([^\]]+)\]\(([^)]+)\)')
FOOTNOTE_LINK_TEXT_RE = re.compile(r'\[([^\]]+)\]\[(\d+)\]')
FOOTNOTE_LINK_URL_RE = re.compile(r'\[(\d+)\]:\s+(\S+)')
def find_md_links(md):
""" Return dict of links in markdown """
links = list(INLINE_LINK_RE.findall(md))
footnote_links = dict(FOOTNOTE_LINK_TEXT_RE.findall(md))
footnote_urls = dict(FOOTNOTE_LINK_URL_RE.findall(md))
for key in footnote_links.keys():
links.append((footnote_links[key], footnote_urls[footnote_links[key]]))
return links
我在 python3 中测试
[h](http://google.com) and [h](https://goog.e.com)