2

这是我的情况。我想为链接识别 Markdown(在这种情况下,只有一种特定样式的链接很好,它是这种格式:[link text](url "optional title"),我想要做的是将此 Markdown 文本放入<pre>标签中,并将 URL 适当地包裹在<a>标签中.

一个伪例子:

转变

[link text](url "optional title")

[link text](<a href='url'>url</a> "optional title")

所以我挖掘了 Markdown 解析器使用的正则表达式,它是这样的:

/*
text = text.replace(/
    (                           // wrap whole match in $1
        \[
        (
            (?:
                \[[^\]]*\]      // allow brackets nested one level
                |
                [^\[\]]         // or anything else
            )*
        )
        \]
        \(                      // literal paren
        [ \t]*
        ()                      // no id, so leave $3 empty
        <?(                     // href = $4
            (?:
                \([^)]*\)       // allow one level of (correctly nested) parens (think MSDN)
                |
                [^()\s]
            )*?
        )>?                
        [ \t]*
        (                       // $5
            (['"])              // quote char = $6
            (.*?)               // Title = $7
            \6                  // matching quote
            [ \t]*              // ignore any spaces/tabs between closing quote and )
        )?                      // title is optional
        \)
    )
/g, writeAnchorTag);
*/

text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()<?((?:\([^)]*\)|[^()\s])*?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g, writeAnchorTag);

漂亮评论中的细分有助于了解发生了什么,显然我需要做的就是将$4submatch替换为<a href='$4'>$4</a>.

但我当然不能这样做str.replace(re,"<a href='$4'>$4</a>");,因为那样会用纯链接替换我的整个 Markdown 链接标记(包括链接文本和可选标题)。我希望纯链接显示在原始 Markdown 中,这样它看起来仍然像原来的 Markdown 一样<pre>(但现在有一个可点击的链接)。

那么,让我们看看...

提取物$4

var group_4 = str.replace(re, "$4"); // Does anybody know a more efficient way to do this? I'm not trying to replace I just need to get the 4th group

好吧,我被卡住了,因为我想坚持"<a href='"+group_4+"'>"+group_4+"</a>"作为$4.

有人对我有提示吗?我很确定这是可以做到的,我怀疑它也可以优雅地完成。

我已经找到了一种潜在的解决方案(这是错误的),即去掉 group 之外的正则表达式部分$4。我认为这还不够,因为它不会根据链接内容进行任何实际的链接检测(即,您可以使用根本不是真正链接的东西来定义 Markdown 链接)。所以我应该使用原始的正则表达式,以确保我转换成的<a>实际上是(Markdown 内联样式)链接的一部分。

4

1 回答 1

0

我想我有办法用我已经知道的东西来解决这个问题。只需更换原厂零件即可。这意味着必须有其他子匹配项覆盖了 before 和 after 的整个表达式$4。假设有一个组$x包含从开始到字符串的匹配$4,另一个组$y包含从字符串结尾$4到结尾的匹配,我所要做的就是str.replace(re,"$x<a href='$4'>$4</a>$y")完成它。

现在看看是否可以修改我们的正则表达式以不更改其接受的语言,同时为我提供这些组。

更新:再看一会儿它实际上是非常基本的:

str.replace(re,"[$2]($4 $5)")

让我以 99% 的方式完全复制原始输入,唯一不正确的部分是之间的空间$4$5输入中的空间,[ \t]*所以我所要做的就是将其包装到原始输入中的一个新组中正则表达式。我相信它会变成$5这样:

/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()<?((?:\([^)]*\)|[^()\s])*?)>?([ \t]*)((['"])(.*?)\6[ \t]*)?\))/g
                                                                      ^      ^

下面一行上的克拉表示添加括号的位置。

str.replace(re,"[$2]($4$5$6)")

应该产生确切的原件,所以

str.replace(re,"[$2](<a href='$4'>$4</a>$5$6)")

应该这样做。

现在剩下的就是设计一种仅在这些链接结构之外转义 HTML 的方法,因为我不想转义锚标记。嗯。

于 2012-07-09T22:56:09.257 回答