Javascript 不带查找的正则表达式,用于加粗标记

Javascript 不带查找的正则表达式,用于加粗标记,javascript,regex,Javascript,Regex,因此,我正在尝试为JavaScript编写一个正则表达式,它将允许我用标记替换**,作为一种自滚动标记到HTML转换器 e、 g **bold**->bold 但是 \**not**->**not**,因为*已转义 我有以下正则表达式,它似乎工作得很好: /(?<!\\)(?:\\\\)*(\*\*)([^\\\*]+)(\*\*)/g 但这需要我反转字符串,这是不需要的,因为我需要支持多字节字符()。我并不完全反对使用该答案中提到的库,但如果可能的话,我更喜欢不需要添加库的解决方案 有

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

e、 g

**bold**
->
bold

但是

\**not**
->
**not**
,因为
*
已转义

我有以下正则表达式,它似乎工作得很好:

/(?<!\\)(?:\\\\)*(\*\*)([^\\\*]+)(\*\*)/g
但这需要我反转字符串,这是不需要的,因为我需要支持多字节字符()。我并不完全反对使用该答案中提到的库,但如果可能的话,我更喜欢不需要添加库的解决方案

有没有一种不使用look behinds重写正则表达式的方法

编辑:


在进一步思考这个问题之后,我甚至开始怀疑正则表达式是否是解决这个问题的最佳方法,但我将不感兴趣地把这个问题留给大家。

解决缺少lookbehind的一种方法是首先匹配不需要的模式,然后使用交替匹配所需的模式。然后应用条件替换,用它们自己替换不需要的模式,并用实际需要的模式替换所需的模式

在您的特定情况下,这意味着首先匹配
\*
,然后再匹配
***
。然后使用

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

JavaScript替换演示:

函数转换(){
var md=document.getElementById(“md”).value;
变量re=/\\\\\\\\*\\*\**(?:\\\\\\\\\*\*\*\*\*。(?!\*)\*[\S\S])*?)\*/g;
var html=md.replace(re,函数(match,p1){
返回match.startsWith(“\\”)?match:“”+p1+””;
});
document.getElementById(“html”).value=html;
}

医学博士
**大胆的**
**富吧**
**foo\**酒吧**
**fo\\\**条****
\**粗体****
\\**大胆的**
**多重
线**
HTML

Convert
试试这个公式,不要向前看(向后看):

(?:(?:[\\])\**(?:.+?)\****。(?:[^\\\n]\\ ^)\**(.+)\*)


考虑以下正则表达式:

/(.*?)(\\\\|\\\*|\*\*)/g
您可以将其视为标记器。它对某些(或无)文本进行非贪婪匹配,后跟一个特殊字符序列
\\
\*
,最后是
**
。按此顺序匹配可确保像
**foo\**bar\\**
这样的奇怪边缘情况得到正确处理(
foo\**bar\
)。这就产生了一个非常简单的
String.prototype.replace
,在它的replacement函数中使用一个
开关。布尔
bold
标志帮助我们决定是将
**
替换为
还是

body{font系列:'Helvetica Neue',Helvetica,sans serif}
text区域{显示:块;字体系列:单空格;宽度:100%;边距底部:1em}
div{填充:2px;背景色:浅黄花}
输入
aaa**BBB**ccc\**ddd**EEE\\\**fff\**ggg**HHH**
输出HTML:
呈现的HTML:

输入的结果应该是什么
**foo*bar**
**foo\**bar**
?我希望分别是
foo*bar
foo\**bar
。很可能我的正则表达式没有涵盖所有情况,因为我甚至还没有能够测试它。我不太关心缺少的边缘案例,而更关心的是编写正则表达式并查看后面的内容,但是指出缺少的案例仍然很有帮助,所以谢谢!我也不是超级,超级关注边缘案例,因为这是在一个管理工具中使用的,像这样的奇怪案例并不是一个真正的问题。你真的希望字符串格式不正确吗?您知道,如果字符串格式不正确,即使是正确的解析器也会产生错误的结果。请尝试@WiktorStribiżew您所说的格式错误的字符串是什么意思?如果您有
\**而不是****
“****”
,则会突出显示该字符串。感谢您详细解释了消除外观落后的一般策略。在执行
拆分(“\n”)
之后,我正在逐行解析字符串,因此甚至不需要多行!
\\\\|\\\*|\*\*((?:\\\\|\\\*\*|\*(?!\*)|[\S\s])*?)\*\*
/(.*?)(\\\\|\\\*|\*\*)/g
const TOKENIZER = /(.*?)(\\\\|\\\*|\*\*)/g;

function render(str) {
  let bold = false;
  return str.replace(TOKENIZER, (_, text, special) => {
    switch (special) {
      case '\\\\':
        return text + '\\';
      case '\\*':
        return text + '*';
      case '**':
        bold = !bold;
        return text + (bold ? '<strong>' : '</strong>');
      default:
        return text + special;
    }
  });
}