admin管理员组

文章数量:1355107

I'm trying to escape the subset of markdown that Discord supports (*, _, `, ~). Characters that are already escaped should not have additional backslashes added. This is what I have:

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

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

I'm trying to escape the subset of markdown that Discord supports (*, _, `, ~). Characters that are already escaped should not have additional backslashes added. This is what I have:

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

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

This works fine, minus the fact that multiple markdown characters against each other will not all be escaped. I'm not sure how to expand this to allow for that, without making the expression absurdly plicated.

Share Improve this question edited Sep 17, 2016 at 7:19 Alan Moore 75.3k13 gold badges107 silver badges161 bronze badges asked Sep 17, 2016 at 4:31 Gawdl3yGawdl3y 2301 gold badge3 silver badges15 bronze badges 2
  • 2 If a character already has a backslash in front of it, that doesn't necessarily mean it's escaped, e.g. \\~ – qxz Commented Sep 17, 2016 at 6:29
  • @qxz You are entirely correct. – Gawdl3y Commented Sep 18, 2016 at 5:56
Add a ment  | 

3 Answers 3

Reset to default 4

I would suggest unescaping any already-escaped characters, then escaping everything again:

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));

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||'));

It'll add a backslash before any of the characters in the regular expression if there is 2 of them.

I know this is in ruby, not js, but this can be trivially translated to JS, it escapes all known discord special characters (+ prevent previews with links)

  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

(I'm posting this here as I'm sure it could help future readers and this seems to be the only place talking about this issue)

And here is a string full of Discord formatting things as a bonus:

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. https://mathiasbynens.be/demo/url-regex
Code: `inline`

```
block
```

```ruby
block with language
```

Spoiler: ||spoiler||

本文标签: javascriptEscaping Discord subset of markdownStack Overflow