【问题标题】:using regex to fix markdown input - link labels使用正则表达式修复降价输入 - 链接标签
【发布时间】:2014-03-06 07:16:09
【问题描述】:

我们遇到了一些降价内容的问题。我们使用的一些 jquery 编辑器没有编写正确的 markdown 语法。 Embedded Links 使用“标签”格式,将链接放在文档底部(就像 StackOverflow 编辑器一样)。我们遇到的问题是链接有时以非标准方式格式化。虽然允许它们以 0,3 个空格作为前缀,但有些以 4 个空格出现(您可能会注意到 StackOverflow 在 javascript 中强制使用 2 个空格)——这在降价解析器中将其触发为 preformatted text

举个简单的例子:

This is a sample doucument that would have inline links. 
[Example 0][0], [Example 1][1], [Example 2][2] , [Example 3][3] , [Example 4][4]

[0]: http://example.com
 [1]:      http://example.com/1
  [2] : http://example.com/2
   [3]: http://example.com/3
    [4]  : http://example.com/4

我想将最后一部分重新格式化为正确的降价:

[0]: http://example.com
[1]: http://example.com/1
[2]: http://example.com/2
[3]: http://example.com/3
[4]: http://example.com/4

我在试图想出正确的正则表达式来捕捉“标签”部分时遇到了困难。我可以很好地抓住该部分中的标签 - 但该部分正在躲避我。

这是我目前所拥有的:

RE_footnote = re.compile("""
    (?P<labels_section>
        ^[\t\ ]*$                             ## we must start with an empty line
        \s+                       
        (?P<labels>
            (?P<a_label>
                ^
                    [\ \t]*                     ## we could have 0-n spaces or tabs
                    \[                          ## BRACKET - open
                        (?P<id>
                            [^^\]]+
                        )
                    \]                          ## BRACKET - close
                    \s*
                    :                           ## COLON
                    \s*
                    (?P<link>                   ## WE want anything here
                        [^$]+
                    )
                $
            )+                                  ## multiple labels
        )
    )
""",re.VERBOSE|re.I|re.M)

我遇到的具体问题:

  1. 我不知道如何允许 1 个或多个“空白行”。这会触发一个无效的正则表达式,没有可重复的内容:

    (?: ## 将其包装在非捕获组中,需要 1+ 次出现 ^[\t\]*$
    )+

  2. 如果在组 \s+ 之前没有空格匹配,则匹配将不起作用。我不知道是什么/为什么。

  3. 我希望它仅在文档的末尾匹配,以确保我们只修复这些 javascript 错误(而不是文档核心的内容)。我所有尝试使用\z 的尝试都失败了,很悲惨。

谁能给点建议?


更新

这行得通:

RE_MARKDOWN_footnote = re.compile("""
    (?P<labels_section>
        (?:                            ## we must start with an empty / whitepace-only line
            ^\s*$
        )                              
        \s*                             ## there can be more whitespace lines
        (?P<labels>
            (?P<a_label>
                ^
                    [\ \t]*                     ## we could have 0-n spaces or tabs
                    \[                          ## BRACKET - open
                        (?P<id>
                            [^^\]]+
                        )
                    \]                          ## BRACKET - close
                    \s*
                    :                           ## COLON
                    \s*
                    (?P<link>                   ## WE want anything here
                        [^$]+
                    )
                $
            )+                                  ## multiple labels
        )
        \s*                                     ## we might have some empty lines 
        \Z                                      ## ensure the end of document
    )
""",re.VERBOSE|re.I|re.M)

【问题讨论】:

  • 有人使用他们的正则表达式??这是什么魔法?! :)
  • 我可能误解了你的问题,但\t 匹配制表符,而不是空行。我想你可能正在寻找\n
  • 一般的事情:每当我使用正则表达式时,我都会尽可能地限制我正在正则表达式的域。就像这里:是否可以从字符串的末尾开始并向后看'[0]',将其切出,正则表达式清理,重新拼接?这似乎是一个更容易解决的问题,并且会产生实际可维护的代码。
  • \s* 不会匹配任意数量的空行(与re.M 标志一起)?对于问题 2,请记住 $ 实际上并不匹配换行符,而是换行符之前的位置,所以这就是为什么你仍然需要匹配它之后的换行符。
  • 也许 [^\n]+ 就是你想要的。

标签: python regex markdown


【解决方案1】:

我刚从零开始;像这样更简单的东西不能工作有什么原因吗?

^\s*                # beginning of the line; may include whitespace
  \[                # opening bracket
     (?P<id>\d+)    # our ID
  \]                # closing bracket
\s*                 # optional whitespace
  :                 # colon
\s*                 # optional whitespace
  (?P<link>[^\n]+)  # our link is everything up to a new line
$                   # end of the line

这是使用全局和多行修饰符gm 完成的。将匹配项替换为:[\id]: \link。这是一个工作示例:http://regex101.com/r/mM8dI2

【讨论】:

  • 你改变了我! :-)(很高兴为车队添加了一些东西。)
  • 是的,为@ooga 提供[^\n]+ 的道具。我最初使用了一个更粗俗的惰性匹配[^$]+?
  • 我实际上认为美元符号根本不起作用。不过,我在 perl 中对其进行了测试,它抱怨 [^$]+ 的“不匹配 [in regex”。
  • 是的,它有效。但它很丑。有很多东西可以改进(性能,可读性)。没有您和@ooga,它将无法正常工作。丑陋的代码通过了我所有的测试,所以我现在在遗留内容上运行它。本周晚些时候,我将根据您的代码中的一些想法对其进行清理,并可能将其集成为过滤器或验证器。
  • 在遗留内容上出现一些错误时重写了测试套件。你的一个稍微修改过的版本比我的做得更好——非常感谢!如果你有兴趣,这里是我写的测试——gist.github.com/jvanasco/8919972。我最终匹配了一个我没有正确测试的误报(现在是),所以我放弃了它。
猜你喜欢
  • 2021-08-28
  • 1970-01-01
  • 2014-06-17
  • 2021-05-29
  • 1970-01-01
  • 1970-01-01
  • 2010-11-19
  • 2021-05-30
  • 2010-10-27
相关资源
最近更新 更多