4

Telegram Bot API 4.5 comes with new parse mode, MarkdownV2. At the same time these _ * [ ] ( ) ~ > # + - = | { } . ! characters must be escaped with the preceding character \.

.replace(/[-.+?^$[\](){}\\]/g, '\\$&') used as solution for adding escape character which works very well but unfortunately this solution does effect hyperlink method [inline URL](http://www.example.com/) because it replace \[inline URL\]\(http://www.example\.com/\)

Solution

bot.on('text', (ctx) => {
  const { chat } = ctx.message;
  const msgs = `Here is the [rules](https://telegra.ph/rules-05-06) Please read carefully and give the details which mentioned below.
*Name:*
*Place:*
*Education:*
*Experience:*
You can also call me on (01234567890)
__For premium service please contact with admin__`;

  const msgmsgWithEscape = msgs.replace(/[-.+?^$[\](){}\\]/g, '\\$&')

  ctx.telegram.sendMessage(
    chat.id,
    msgmsgWithEscape,
    {
      parse_mode: 'MarkdownV2',
    }
  )
});

Result

enter image description here

Mo.
  • 26,306
  • 36
  • 159
  • 225

1 Answers1

4

To avoid escaping links formatted like [...](http...) you may match them and capture into a group and just match all the chars to escape in other contexts. Then, examine the Group 1 value and if it is not empty, replace with Group 1 value, else, replace with the escaped char:

const msgs = `Here is the [rules](https://telegra.ph/rules-05-06) Please read carefully and give the details which mentioned below.
*Name:*
*Place:*
*Education:*
*Experience:*
You can also call me on (01234567890)
__For premium service please contact with admin__`;

const msgmsgWithEscape = msgs.replace(/(\[[^\][]*]\(http[^()]*\))|[_*[\]()~>#+=|{}.!-]/gi,
    (x,y) => y ? y : '\\' + x)

console.log(msgmsgWithEscape);
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • 1
    You should add a **!** and **#** to the regExp: '_', '*', '[', ']', '(', ')', '~', '\`', '>', '#', '+', '-', '=', '|', '{', '}', '.', '!' must be escaped – Lee Twelve Oct 20 '20 at 07:30
  • @LeeTwelve I thought the main trouble was matching those chars outside strings within brackets, but you are right. I added the missing chars. – Wiktor Stribiżew Oct 20 '20 at 07:48
  • You should add a step of preprocessing the titles of the links. Something along the lines `msgmsgWithEscape = msgmsgWithEscape.replace(/\[([^\][]*)]\(/g, (x,y) => "[" + y.replace(/[-.+?^$[\](){}\\!#]/g, '\\$&') + "]\(" );` – Dima Mironov Oct 13 '21 at 14:49