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