Python 标记解析器中的正则表达式问题
我试图用python制作一个标记解析器,不是因为它有用,而是因为它很有趣,因为我试图学习正则表达式Python 标记解析器中的正则表达式问题,python,regex,markdown,Python,Regex,Markdown,我试图用python制作一个标记解析器,不是因为它有用,而是因为它很有趣,因为我试图学习正则表达式 #! /usr/bin/env python #-*- coding: utf-8 -*- import re class Converter: def markdown2html(self, string): string = re.sub('\*{3}(.+)\*{3}', '<strong>\\1</strong>', string)
#! /usr/bin/env python
#-*- coding: utf-8 -*-
import re
class Converter:
def markdown2html(self, string):
string = re.sub('\*{3}(.+)\*{3}', '<strong>\\1</strong>', string)
string = re.sub('\*{2}(.+)\*{2}', '<i>\\1</i>', string)
string = re.sub('^#{1}(.+)$', '<h1>\\1</h1>', string, flags=re.MULTILINE)
string = re.sub('^#{2}(.+)$', '<h2>\\1</h2>', string, flags=re.MULTILINE)
return string
markdown_sting = """
##h2 heading
#H1 heading
This should be a ***bold*** char
#anohter h1
anohter ***bold***
this is a **italic** string
"""
converter = Converter()
print converter.markdown2html(markdown_sting)
它打印
<h1>#h2 heading</h1>
<h1>H1 heading</h1>
This should be a <strong>bold</strong> char
<h1>anohter h1</h1>
anohter <strong>bold</strong>
this is a <i>italic</i> string
如您所见,它不解析h2标记。我哪里出错了?当解析器看到时,它会替换h1。然后它尝试对h2进行替换,但是没有字符串,因为在解析h1部分时已经替换了一个哈希
一个简单的解决方法是交换订单:
string = re.sub('^#{2}(.+)$', '<h2>\\1</h2>', string, flags=re.MULTILINE)
string = re.sub('^#{1}(.+)$', '<h1>\\1</h1>', string, flags=re.MULTILINE)
一般来说,当您对数据应用转换时,您应该将其从限制性最强的顺序排列到限制性最低的顺序,以避免这些问题。当您看到解析器时,它会替换h1。然后它尝试对h2进行替换,但是没有字符串,因为在解析h1部分时已经替换了一个哈希
一个简单的解决方法是交换订单:
string = re.sub('^#{2}(.+)$', '<h2>\\1</h2>', string, flags=re.MULTILINE)
string = re.sub('^#{1}(.+)$', '<h1>\\1</h1>', string, flags=re.MULTILINE)
一般来说,当您将转换应用于数据时,应该将其从限制性最强的顺序排列到限制性最低的顺序,以避免这些问题。这些正则表达式是按顺序计算的。h1正则表达式将获取以a开头的任何行,并将其转换为。因此,当它到达h2正则表达式时,该行不再以开头。交换这两个表达式。这些正则表达式按顺序计算。h1正则表达式将获取以a开头的任何行,并将其转换为。因此,当它到达h2正则表达式时,该行不再以开头。交换这两个表达式。更合适、更有效的方法可能是比较字符串的前几个字符,然后执行简单的字符串替换
def markdown2html(self, string):
if string[0:2] == "##":
string = string.replace( "##", "<h2>" ) + "</h2>"
if string[0] == "#":
string = string.replace( "##", "<h1>" ) + "</h1>"
return string
这样,您就可以进行简单的列表操作,而不是正则表达式。但在所有情况下,顺序都很重要更合适、更有效的方法可能是比较字符串的第一个字符,然后执行简单的字符串替换
def markdown2html(self, string):
if string[0:2] == "##":
string = string.replace( "##", "<h2>" ) + "</h2>"
if string[0] == "#":
string = string.replace( "##", "<h1>" ) + "</h1>"
return string
这样,您就可以进行简单的列表操作,而不是正则表达式。但在所有情况下,顺序都很重要,您可以通过确保标题文本的第一个字符不是哈希符号来确保只匹配所需数量的哈希符号。这可以通过如下方式使用[^]实现:
string = re.sub('^#{1}([^#].*)$', '<h1>\\1</h1>', string, flags=re.MULTILINE)
string = re.sub('^#{2}([^#].*)$', '<h2>\\1</h2>', string, flags=re.MULTILINE)
这样,规则的顺序就不重要了,使规则更加健壮。通过确保标题文本的第一个字符不是哈希符号,可以确保只匹配所需数量的哈希符号。这可以通过如下方式使用[^]实现:
string = re.sub('^#{1}([^#].*)$', '<h1>\\1</h1>', string, flags=re.MULTILINE)
string = re.sub('^#{2}([^#].*)$', '<h2>\\1</h2>', string, flags=re.MULTILINE)
这样,规则的顺序就不重要了,使规则更加健壮。当您开始解析h2标记时,它的行已经被h1规则解析。如果您确实想学习正则表达式,请阅读:。但是现在,你可以通过阅读获得一个良好的开端。您应该使用原始字符串来存储模式。当您开始解析h2标记时,其行已被h1规则解析。如果您确实想学习正则表达式,请阅读:。但是现在,你可以通过阅读获得一个良好的开端。您应该使用原始字符串来存储模式。您可以使用而不是切片…您可以使用而不是切片…谢谢,我认为这是最好的方式!谢谢,我想这是最好的方式!