Javascript JS RegExp不使用字母字符

Javascript JS RegExp不使用字母字符,javascript,regex,Javascript,Regex,作为自定义WYSIWYG编辑器的一部分,我们被要求在启用时实现自动表情解析。为此,我们使用正则表达式将字符组合替换为其关联的PNG文件 下面是处理此问题的代码的相关部分(它由contenteditable元素上的onkeyup事件触发;我已将其修剪回相关部分): 我们将系统中使用的所有表情符号定义在一个对象内部,该对象由字符组合本身引用,如下所示: this.emoji = { ':)' : [ '1F642', 'Smiling face' ], ':-)' : [ '1F6

作为自定义WYSIWYG编辑器的一部分,我们被要求在启用时实现自动表情解析。为此,我们使用正则表达式将字符组合替换为其关联的PNG文件

下面是处理此问题的代码的相关部分(它由
contenteditable
元素上的
onkeyup
事件触发;我已将其修剪回相关部分):

我们将系统中使用的所有表情符号定义在一个对象内部,该对象由字符组合本身引用,如下所示:

this.emoji = {
    ':)'  : [ '1F642', 'Smiling face' ],
    ':-)' : [ '1F642', 'Smiling face' ],
    ':D'  : [ '1F601', 'Happy face' ],
    ':-D' : [ '1F601', 'Happy face' ],
    ':\'(': [ '1F622', 'Crying face' ],
    ':('  : [ '1F614', 'Sad face' ],
    ':-(' : [ '1F614', 'Sad face' ],
    ':P'  : [ '1F61B', 'Cheeky' ],
    ':-P' : [ '1F61B', 'Cheeky' ],
    ':/'  : [ '1F615', 'Unsure face' ],
    ':-/' : [ '1F615', 'Unsure face' ],
    'B)'  : [ '1F60E', 'Too cool face' ],
    'B-)' : [ '1F60E', 'Too cool face' ]
};
现在,奇怪的是,任何包含字母字符的字符组合都不会被替换,并且会使
re.test()
函数失败。例如:
:)
:-)
:(
:”(
都被替换了,没有问题。但是,
:D和
B)
没有问题

有人能解释为什么alpha字符在RegExp中引起问题吗


问题在于,
\B
依赖于上下文,如果有一个单词字符开始模式,则输入字符串中必须有一个单词字符出现在该字符之前,以进行匹配。同样的方式,在模式末尾,
\B
在模式末尾需要相同类型的符号出现在后面

为了避免这个问题,通常使用基于查找的解决方案:
(?。但是,在JS中,不支持查找。稍后可以使用捕获组和替换函数中的反向引用来解决此问题

因此,要正确替换这些情况,您需要将代码的这部分更改为

var re = new RegExp( '(^|\\W)' + _self.regexpEscape(i) + '(?!\\w)' ),
   em = _self.emoji[i]; // match the pattern when not preceded and not followed by a word character

if( re.test($html) )
{
   var replace = '<img class="lw-emoji" height="16" src="'+(url + em[0] + '.png')+'" alt="'+em[1]+'" />';
   this.insertAtCaret( replace );

   _self.$editor.html(function() { return $(this).html().replace(re, '$1'); }); // restore the matched symbol (the one \W matched) with $1
}
var re=new RegExp('(^ |\\W)+\u self.regexpEscape(i)+'(?!\\W),
em=_self.emoji[i];//在不后跟单词字符的情况下匹配模式
如果(重新测试($html))
{
var替换=“”;
本图为插入式混凝土(替换);
_self.$editor.html(function(){return$(this).html().replace(re,$1');});//用$1还原匹配的符号(匹配的符号)
}

这是我的第一个想法。

@Tushar不起作用,并且破坏了以前使用
\\B
时起作用的其他替换。您正在使用带有
g
-标记的regex的
re.test
。在这种情况下,您无法获得一致的结果。请删除
/g
,或者使用不带
/g
标记的副本
re.test
(更换时,可以使用
/g
-regex)。@stribizev删除
/g
标志会产生相同的结果。
:)
已正确替换;
:D
未正确替换。因为
\B
需要在
\D
后加一个单词字符。
\B
的内容类型混合。这是一种不正确的方法。您需要使用
(?!\\w)
而不是第二个
\\B
。此外,我发现第一个
\\B
也是如此。您需要使用
(^ |\\W)
。好的,我将添加它作为答案。
this.emoji = {
    ':)'  : [ '1F642', 'Smiling face' ],
    ':-)' : [ '1F642', 'Smiling face' ],
    ':D'  : [ '1F601', 'Happy face' ],
    ':-D' : [ '1F601', 'Happy face' ],
    ':\'(': [ '1F622', 'Crying face' ],
    ':('  : [ '1F614', 'Sad face' ],
    ':-(' : [ '1F614', 'Sad face' ],
    ':P'  : [ '1F61B', 'Cheeky' ],
    ':-P' : [ '1F61B', 'Cheeky' ],
    ':/'  : [ '1F615', 'Unsure face' ],
    ':-/' : [ '1F615', 'Unsure face' ],
    'B)'  : [ '1F60E', 'Too cool face' ],
    'B-)' : [ '1F60E', 'Too cool face' ]
};
var re = new RegExp( '(^|\\W)' + _self.regexpEscape(i) + '(?!\\w)' ),
   em = _self.emoji[i]; // match the pattern when not preceded and not followed by a word character

if( re.test($html) )
{
   var replace = '<img class="lw-emoji" height="16" src="'+(url + em[0] + '.png')+'" alt="'+em[1]+'" />';
   this.insertAtCaret( replace );

   _self.$editor.html(function() { return $(this).html().replace(re, '$1'); }); // restore the matched symbol (the one \W matched) with $1
}