使用Python

时间:2015-06-09 14:16:34

标签: python regex markdown

我正在尝试从Markdown中提取锚文本和关联的网址。我见过this个问题。不幸的是,answer似乎并没有完全回答我的想法。

在Markdown中,有两种方法可以插入链接:

示例1:

[anchor text](http://my.url)

示例2:

[anchor text][2]

   [1]: http://my.url

我的脚本看起来像这样(请注意我使用的是regex,而不是重复):

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正确捕捉锚文本?

3 个答案:

答案 0 :(得分:3)

  

如何从Markdown正确捕捉锚文本?

将其解析为结构化格式(例如,html),然后使用适当的工具提取链接标签和地址。

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解析器,这似乎是集中精力的错误位置。

答案 1 :(得分:1)

修改@mreinhardt解决方案以返回所有对 A_Col B_Col C_Col BC_Col 0 home my house I have a new house [my, house, I, have, a, new, house] 1 paper research paper my mobile phone is broken [research, paper, my, mobile, phone, is, broken] 2 NaN NaN zoe zaczek who [zoe, zaczek, who] 3 NaN NaN two per cent [two, per, cent] 的列表(而不是字典):

(text, link)

我在python3中使用repeated链接测试为:

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
    

答案 2 :(得分:0)

你可以用几个简单的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']