逃逸 Discord 子集的 markdown

3

我正在尝试转义Discord支持的Markdown子集(*_`~)。 已转义的字符不应添加额外的反斜杠。 这是我拥有的:

function escapeMarkdown(text) {
 return text.replace(/([^\\]|^|\*|_|`|~)(\*|_|`|~)/g, '$1\\$2');
}

console.log(escapeMarkdown('*test* _string_ ~please~ `ignore` *_`~kthx \*  \\~'));

这个可以正常工作,但是多个markdown字符放在一起时,并不会全部被转义。我不确定如何扩展它以允许这样做,而不使表达式变得非常复杂。


2
如果一个字符已经有反斜杠在它前面,并不一定意味着它被转义了,例如 \\~ - qxz
@qxz 你是完全正确的。 - Gawdl3y
3个回答

4
我建议您先取消转义任何已经转义的字符,然后重新转义所有内容:

function escapeMarkdown(text) {
  var unescaped = text.replace(/\\(\*|_|`|~|\\)/g, '$1'); // unescape any "backslashed" character
  var escaped = unescaped.replace(/(\*|_|`|~|\\)/g, '\\$1'); // escape *, _, `, ~, \
  return escaped;
}

var str = '*test* _string_ ~please~ `ignore` *_`~kthx \*  \\~ C:\\path\\to\\file';
console.log("Original:");
console.log(str);
console.log("Escaped:");
console.log(escapeMarkdown(str));


这实际上非常接近我自己最终想出并正在使用的内容,但它并不是没有副作用。它确实解决了现有的Markdown字符上存在的双重转义问题,但它也完全从字符串中消除了现有的反斜杠。如果该字符串应包含带有\的原始反斜杠(如Windows路径),则它将完全从结果中消失。 - Gawdl3y
修改第一个正则表达式,只对5个特殊字符进行反转义。 - qxz

1

I had to make a markdown escape function for my NodeJS discord bot recently, here's the code I used.

var markdownEscape = function(text) {
   return text.replace(/((\_|\*|\~|\`|\|){2})/g, '\\$1');
};

console.log(markdownEscape('||some spoiler text||'));

如果正则表达式中有两个相同的字符,它将在该字符前添加反斜杠。

我将其翻译为 PHP:preg_replace("/((\_|\*|\~|\||){2})/", '\\$1', $txt);` - beppe9000
请注意,这对斜体无效,因为只需要一个星号。 - Nate Levin

0

我知道这是用Ruby编写的,而不是JS,但是它可以轻松地翻译成JS,它可以转义所有已知的Discord特殊字符(+防止链接预览)

  def escape(str)
    # \ -> \\
    str = str.gsub("\\") { "\\\\" }
    # - -> \_
    str = str.gsub('_') { "\\_" }
    # * -> \*
    str = str.gsub('*') { "\\*" }
    # ~ -> \~
    str = str.gsub('~') { "\\~" }
    # ` -> \`
    str = str.gsub('`') { '\\`' }
    # | -> \|
    str = str.gsub('|') { '\\|' }
    # urls without previews
    str = str.gsub(/https?:\/\/[\S]+/) { |url| "<#{url}>" }

    str
  end

(我在这里发布这篇文章,因为我相信它可能会帮助未来的读者,并且这似乎是唯一谈论此问题的地方)
(以下是一个充满 Discord 格式的字符串作为奖励)
Italics *italics* or _italics_
Underline italics __*underline italics*__
Bold **bold**
Underline bold __**underline bold**__
Bold Italic ***bold italics***
underline bold italics __***underline bold italics***__
Underline __underline__
Strikethrough  ~~Strikethrough~~
Link https://google.com https://mathiasbynens.be/demo/url-regex
Code: `inline`

```
block
```

```ruby
block with language
```

Spoiler: ||spoiler||

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接