Skip to main content
 首页 » 编程设计

python之从 markdown 中解析元素

2025年05月04日11kenshinobiy

我想为特定元素(例如链接)解析 markdown 文件并从这些元素中获取值,但我找不到使用 python-markdown 包的方法。 是否可以使用所述包来完成它,或者我应该将 .md 渲染成 html,然后使用诸如 beautiful-soup 之类的工具来解析 html 以获取元素和/或结构?

请您参考如下方法:

python3 选项是 ReParser

pip install ReParser 

其文档中的示例(粘贴在末尾)将输出:

[('Hello ', {}), 
 ('bold', {'is_bold': True}), 
 (' world!', {}), 
 ('\n', {'segment_type': 'LINE_BREAK'}), 
 ('You can ', {}), 
 ('try ', {'is_bold': True}), 
 ('this', {'is_bold': True, 'is_italic': True}), 
 (' awesome', {'is_bold': True}), 
 (' ', {}), 
 ('link', {'link_target': 'http://www.eff.org'}), 
 ('.', {})] 

示例代码是:

import re 
from pprint import pprint 
from reparser import Parser, Token, MatchGroup 
 
boundary_chars = r'\s`!()\[\]{{}};:\'".,<>?«»“”‘’*_~=' 
b_left = r'(?:(?<=[' + boundary_chars + r'])|(?<=^))'  # Lookbehind 
b_right = r'(?:(?=[' + boundary_chars + r'])|(?=$))'   # Lookahead 
 
markdown_start = b_left + r'(?<!\\){tag}(?!\s)(?!{tag})' 
markdown_end = r'(?<!{tag})(?<!\s)(?<!\\){tag}' + b_right 
markdown_link = r'(?<!\\)\[(?P<link>.+?)\]\((?P<url>.+?)\)' 
newline = r'\n|\r\n' 
 
url_proto_regex = re.compile(r'(?i)^[a-z][\w-]+:/{1,3}') 
 
def markdown(tag): 
    """Return sequence of start and end regex patterns for simple Markdown tag""" 
    return (markdown_start.format(tag=tag), markdown_end.format(tag=tag)) 
 
def url_complete(url): 
    """If URL doesn't start with protocol, prepend it with http://""" 
    return url if url_proto_regex.search(url) else 'http://' + url 
 
tokens = [ 
    Token('bi1',  *markdown(r'\*\*\*'), is_bold=True, is_italic=True), 
    Token('bi2',  *markdown(r'___'),    is_bold=True, is_italic=True), 
    Token('b1',   *markdown(r'\*\*'),   is_bold=True), 
    Token('b2',   *markdown(r'__'),     is_bold=True), 
    Token('i1',   *markdown(r'\*'),     is_italic=True), 
    Token('i2',   *markdown(r'_'),      is_italic=True), 
    Token('pre3', *markdown(r'```'),    skip=True), 
    Token('pre2', *markdown(r'``'),     skip=True), 
    Token('pre1', *markdown(r'`'),      skip=True), 
    Token('s',    *markdown(r'~~'),     is_strikethrough=True), 
    Token('u',    *markdown(r'=='),     is_underline=True), 
    Token('link', markdown_link, text=MatchGroup('link'), 
          link_target=MatchGroup('url', func=url_complete)), 
    Token('br', newline, text='\n', segment_type="LINE_BREAK") 
] 
 
parser = Parser(tokens) 
text = ('Hello **bold** world!\n' 
        'You can **try *this* awesome** [link](www.eff.org).') 
 
segments = parser.parse(text) 
pprint([(segment.text, segment.params) for segment in segments])