正则匹配表情

Regex matching emoticons

我们正在开展一个项目,希望用户能够同时使用表情符号语法(如 :smile::heart::confused::stuck_out_tongue:)以及普通表情符号(如 :)<3:/:p

我在使用表情符语法时遇到问题,因为有时这些字符序列会出现在:

如何才能找到这些表情符号字符序列,而当其他字符靠近它们时却找不到?

我用于所有表情符号的整个正则表达式都很大,所以这里有一个精简版:

(\:\)|\:\(|<3|\:\/|\:-\/|\:\||\:p)

您可以在此处试用它的实际演示:http://regexr.com/3a8o5

我假设这些表情通常会与 space 前后一起使用。那么 \s 可能就是您要查找的内容,因为它代表白色 space.

那么你的正则表达式将变成

\s+(\:\)|\:\(|<3|\:\/|\:-\/|\:\||\:p)\s

做一个positive look-ahead for a space

([\:\<]-?[)(|\/pP3D])(?:(?=\s))
 |       |      |         |
 |       |      |         |
 |       |      |         |-> match last separating space
 |       |      |-> match last part of the emot
 |       |-> it may have a `-` or not 
 |-> first part of the emoticon

由于您正在使用 javascript,并且您无权环顾四周:

/([\:\<]-?[)|\/pP3D])(\s|$)/g.exec('hi :) ;D');

然后只是 splice() 最后一个条目的结果数组(这很可能是 space)

首先匹配表情符号(处理 :pencil: 示例),然后检查终止符白色space 或换行符:

(\:\w+\:|\<[\/\]?3|[\(\)\\D|\*$][\-\^]?[\:\;\=]|[\:\;\=B8][\-\^]?[3DOPp\@$\*\\)\(\/\|])(?=\s|[\!\.\?]|$)

此正则表达式匹配以下内容(首选表情符号),返回匹配组 1 中的匹配项:

:( :) :P :p :O :3 :| :/ :\ :$ :* :@
:-( :-) :-P :-p :-O :-3 :-| :-/ :-\ :-$ :-* :-@
:^( :^) :^P :^p :^O :^3 :^| :^/ :^\ :^$ :^* :^@
): (: $: *:
)-: (-: $-: *-:
)^: (^: $^: *^:
<3 </3 <
:smile: :hug: :pencil:

除了白色之外,它还支持终端标点作为分隔符space。

您可以在此处查看更多详细信息并进行测试:https://regex101.com/r/aM3cU7/4

您需要关于间距的正则表达式环视。这里的另一个答案建议积极展望,尽管我会双重否定:

(?<!\S)(\:\)|\:\(|<3|\:\/|\:-\/|\:\||\:p)(?!\S)

虽然JavaScript不支持(?<!pattern)look-behind can be mimicked

test_string.replace(/(\S)?(\:\)|\:\(|<3|\:\/|\:-\/|\:\||\:p)(?!\S)/,
                    function([=11=], ) { return  ? [=11=] : replacement_text; });

我所做的只是在您的代码前面加上 (?<!\S) 前缀,在后面加上 (?!\S) 后缀。前缀可确保您不遵循非空白字符,因此唯一有效的前导条目是空格或无(行首)。后缀做同样的事情,确保你后面没有非空白字符。另见 more thorough regex walk-through.

对问题本身的评论之一建议使用 \b(单词边界)标记。我不推荐这些。事实上,这个建议与你想要的相反; \b:/ 确实会匹配 http://,因为 p: 之间有一个单词边界。这种推理会建议 \B (不是单词边界),例如\B:/\B。这更便携(它适用于几乎所有正则表达式解析器,而环顾四周则不能),在这种情况下你可以选择它,但我更喜欢环顾四周。