javascript - Markdown 加粗不带回溯的正则表达式

标签 javascript regex

所以我正在尝试为 JavaScript 编写一个正则表达式,它允许我用标记替换 ** 作为一种自滚动的 Markdown 到 HTML 转换器。

例如

**bold** -> <strong>bold</strong>

但是

\**not** -> **not**因为*被逃脱了。

我有以下似乎运行良好的正则表达式:

/(?<!\\)(?:\\\\)*(\*\*)([^\\\*]+)(\*\*)/g

但是JS不支持lookbehinds!我使用前瞻重写了它:

/(\*\*)([^\\\*]+)*(\*\*)(?!\\)(?:\\\\)*/g

但这需要我反转字符串,这是不受欢迎的,因为我需要支持多字节字符 ( see here )。我并不完全反对使用该答案中提到的库,但我更喜欢一种不需要我在可能的情况下添加的解决方案。

有没有一种方法可以在不使用 look behinds 的情况下重写我的正则表达式?

编辑:

在进一步思考这个问题之后,我什至开始质疑正则表达式是否是解决这个问题的最佳方法,但出于兴趣我会把这个问题搁置。

最佳答案

解决缺少后视的一种方法是首先匹配不需要的模式,然后使用交替匹配所需的模式。然后应用条件替换,将不想要的模式替换为它们自己,将想要的模式替换为您真正想要的。

在您的特定情况下,这意味着匹配 \*首先和**<something>**只有在那之后。然后使用

input.replace(/\\\*|\*\*(.*?)\*\*/, function(m, p1) {
    return m == '\\*' ? m : '<strong>' + p1 + '</strong>';
})

做条件替换。

但真正的正则表达式要复杂得多。首先,您需要避免转义反斜杠本身(即 \\**bold** 应变为 \\<strong>bold</strong> )。所以你需要匹配 \\分别使用与 \* 相同的方式.

二、**之间的表达式和 **也可能包含一些转义星号和斜杠。为了解决这个问题,您需要匹配 \\\**明确地并且(使用交替)仅在此之后任何其他非贪婪的。这可以表示为 (?:\\\\|\\\*\*|\*(?!\*)|[\S\s])*? .

因此最终的正则表达式变为

\\\\|\\\*|\*\*((?:\\\\|\\\*\*|\*(?!\*)|[\S\s])*?)\*\*

演示:https://regex101.com/r/Da35r5/1

JavaScript 替换演示:

function convert() {
  var md = document.getElementById("md").value;
  var re = /\\\\|\\\*|\*\*((?:\\\\|\\\*\*|\*(?!\*)|[\S\s])*?)\*\*/g;
  var html = md.replace(re, function(match, p1) {
    return match.startsWith('\\') ? match : '<strong>' + p1 + '</strong>';
  });
  document.getElementById("html").value = html;
}
<span style="display:inline-block">
MD
<textarea id="md" cols="20" rows="10" style="display:block">
**bold**
**foo * bar **
**foo \** bar**
**fo\\\\** bar** **
\**bold** **
\\**bold**
** multi
line**
</textarea>
</span>

<span style="display:inline-block">
HTML
<textarea id="html" cols="50" rows="10" style="display:block">
</textarea>
</span>

<button onclick="convert()" style="display:block">Convert</button>

关于javascript - Markdown 加粗不带回溯的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44183199/

相关文章:

java - 分割字符串的数字列表

ruby - 使用正则表达式在字符串之间查找内容并切换它们

javascript - 使用 Javascript 从 Joomla 加载数据

javascript - 页脚将自身定位在 HTML 部分的底部

javascript - 为什么要更改 HTML 标签的 class 属性?

Javascript RegEx 查找没有子字符串的变量字符串?

javascript - Uncaught Error : [Ext. 创建] 无法识别的类名/别名 : MyApp. store.LibraryFolderTreeStore

javascript - 如何在 Android 上自动打开 GPS?

java - 如何在java中使用正则表达式/模式删除标签

mysql - 如何在 REGEXP 中转义 MySQL 中的星号 (*)