使用正则表达式转义代码块内的标记
Escaping markup inside code blocks using regex
我目前正在尝试在我的 Web 应用程序中实现我自己对 Discord 降价风格的看法。
我这样做的方法只是通过链接替换方法,每次检查并用适当的 HTML 标记替换语法(我会清理,别担心)。
let description = description.replace(/\`{3}([\S\s]*?)\`{3}/g, '<code></code>')
.replace(/\`(.*)\`/g, '<code class="inline"></code>')
.replace(/~~([\S\s]*?)~~/g, '<s></s>')
我面临的问题是正则表达式也匹配整个代码块内部以及内联代码。这种行为是不希望的。
**bold and
*italic and
__underline and
~~strikethrough~~__***
`~~Not strikethrough~~`
~~`Strikethrough`~~
Normal text
```
~~Not strikethrough~~
```
~~```
Strikethrough
```~~
**bold and
*italic and
__underline and
~~strikethrough~~__***
`~~Not strikethrough~~`
~~`Strikethrough`~~
Normal text
我试过这样的事情:/(?<!`[\S\s])\*([\S\s]*?)\*(?!`)/g
但我无法让它像预期的那样工作。
我仍在学习正则表达式,并且仍然发现很难全神贯注,因此非常感谢任何和所有帮助。
一月。 4. 2021
对不起,我之前没有澄清,但样式应该是“可嵌套的”,或者换句话说可以组合,例如***strong and italic***
应该变成 strong and italic
我更新了输入文本(见上文)以更好地封装所有可能的用例。
您可以使用
let text = "**bold and \n*italic and \n__underline and \n~~strikethrough~~__***\n\n`~~Not strikethrough~~`\n~~`Strikethrough`~~\n\nNormal text\n\n```\n~~Not strikethrough~~\n```\n\n~~```\nStrikethrough\n```~~\n\n**bold and \n*italic and \n__underline and \n~~strikethrough~~__***\n\n`~~Not strikethrough~~`\n~~`Strikethrough`~~\n\nNormal text";
const re = /<code(?:\s[^>]*)?>[\s\S]*?<\/code>|`{3}([\S\s]*?)`{3}|`([^`]*)`|~~([\S\s]*?)~~|\*{2}([\s\S]*?)\*{2}(?!\*)|\*([^*]*)\*|__([\s\S]*?)__/g;
let tmp="";
do {
tmp = text;
text = text.replace(re, (match, a, b, c, d, e, f) => f ? `<u>${f}</u>` : e ? `<i>${e}</i>` : d ? `<b>${d}</b>` : c ? `<s>${c}</s>` : b ? `<code class="inline">${b}</code>` : a ? `<code>${a}</code>` : match);
}
while (text != tmp);
console.log(text);
参见regex demo。
重点是为单次传递设计一个正则表达式,并将字符串部分捕获到单独的组中以应用不同的替换逻辑。
有3个选项匹配
`{3}([\S\s]*?)`{3}
- 三重星号之间的任何子字符串将其捕获到组 1 (x
)
`([^`]*)`
- 单个星号之间的任何子字符串将其捕获到第 2 组 (y
)
~~([\S\s]*?)~~
- ~~
之间的任何子字符串将其捕获到第 3 组 (z
)
参见regex demo。
我目前正在尝试在我的 Web 应用程序中实现我自己对 Discord 降价风格的看法。 我这样做的方法只是通过链接替换方法,每次检查并用适当的 HTML 标记替换语法(我会清理,别担心)。
let description = description.replace(/\`{3}([\S\s]*?)\`{3}/g, '<code></code>')
.replace(/\`(.*)\`/g, '<code class="inline"></code>')
.replace(/~~([\S\s]*?)~~/g, '<s></s>')
我面临的问题是正则表达式也匹配整个代码块内部以及内联代码。这种行为是不希望的。
**bold and
*italic and
__underline and
~~strikethrough~~__***
`~~Not strikethrough~~`
~~`Strikethrough`~~
Normal text
```
~~Not strikethrough~~
```
~~```
Strikethrough
```~~
**bold and
*italic and
__underline and
~~strikethrough~~__***
`~~Not strikethrough~~`
~~`Strikethrough`~~
Normal text
我试过这样的事情:/(?<!`[\S\s])\*([\S\s]*?)\*(?!`)/g
但我无法让它像预期的那样工作。
我仍在学习正则表达式,并且仍然发现很难全神贯注,因此非常感谢任何和所有帮助。
一月。 4. 2021
对不起,我之前没有澄清,但样式应该是“可嵌套的”,或者换句话说可以组合,例如***strong and italic***
应该变成 strong and italic
我更新了输入文本(见上文)以更好地封装所有可能的用例。
您可以使用
let text = "**bold and \n*italic and \n__underline and \n~~strikethrough~~__***\n\n`~~Not strikethrough~~`\n~~`Strikethrough`~~\n\nNormal text\n\n```\n~~Not strikethrough~~\n```\n\n~~```\nStrikethrough\n```~~\n\n**bold and \n*italic and \n__underline and \n~~strikethrough~~__***\n\n`~~Not strikethrough~~`\n~~`Strikethrough`~~\n\nNormal text";
const re = /<code(?:\s[^>]*)?>[\s\S]*?<\/code>|`{3}([\S\s]*?)`{3}|`([^`]*)`|~~([\S\s]*?)~~|\*{2}([\s\S]*?)\*{2}(?!\*)|\*([^*]*)\*|__([\s\S]*?)__/g;
let tmp="";
do {
tmp = text;
text = text.replace(re, (match, a, b, c, d, e, f) => f ? `<u>${f}</u>` : e ? `<i>${e}</i>` : d ? `<b>${d}</b>` : c ? `<s>${c}</s>` : b ? `<code class="inline">${b}</code>` : a ? `<code>${a}</code>` : match);
}
while (text != tmp);
console.log(text);
参见regex demo。
重点是为单次传递设计一个正则表达式,并将字符串部分捕获到单独的组中以应用不同的替换逻辑。
有3个选项匹配
`{3}([\S\s]*?)`{3}
- 三重星号之间的任何子字符串将其捕获到组 1 (x
)`([^`]*)`
- 单个星号之间的任何子字符串将其捕获到第 2 组 (y
)~~([\S\s]*?)~~
-~~
之间的任何子字符串将其捕获到第 3 组 (z
)
参见regex demo。