【问题标题】:Regex matching emoticons正则表达式匹配表情
【发布时间】:2015-03-20 13:15:58
【问题描述】:

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

表情符号语法有问题,因为有时这些字符序列会出现在:

  • 普通字符串或 URL - http://example.com
  • 在表情符号语法中 - :pencil:

我怎样才能找到这些表情符号字符序列,但当其他字符靠近它们时却找不到?

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

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

您可以在此处进行演示:http://regexr.com/3a8o5

【问题讨论】:

  • 为什么不把它分成多个正则表达式呢?另外,你可以做的是匹配边界,例如/\b:\)\b/
  • 如果我没记错的话,TwemojiEmojione 都提供了 JS 代码来处理他们的图像集,并且在 Github、NPM、bower 等上有许多相同的实现。

标签: javascript regex emoji emoticons


【解决方案1】:

创建一个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() 从最后一个条目中取出结果数组(很可能是一个空格)

【讨论】:

    【解决方案2】:

    您想要关于间距的正则表达式环顾四周。这里的另一个答案提出了积极的展望,尽管我会双重否定:

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

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

    test_string.replace(/(\S)?(\:\)|\:\(|<3|\:\/|\:-\/|\:\||\:p)(?!\S)/,
                        function($0, $1) { return $1 ? $0 : replacement_text; });
    

    我所做的只是在您的代码前面加上 (?&lt;!\S) 前缀,在后面加上 (?!\S) 后缀。前缀确保您不跟随非空白字符,因此唯一有效的前导条目是空格或空(行首)。后缀做同样的事情,确保你后面没有非空白字符。另请参阅more thorough regex walk-through

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

    【讨论】:

    • 我正在使用 JavaScript 并且 JS 不支持lookbehinds :(
    • @ChrisBarr 啊,好点。使用替换调用的函数解决。查看我刚刚所做的编辑。
    【解决方案3】:

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

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

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

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

    除了空格之外,它还支持终端标点作为分隔符。

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

    【讨论】:

    • 是的!我已经可以选择表情符号,但这里的关键是在我现有的正则表达式的末尾添加(?=\s|[\!\.\,\?]|$)。谢谢!
    • 匹配 () 时,您还应该检查它是否不是有效括号集的一部分,例如,您不希望它与此处的 8) 表情符号匹配:blah blah bug (reproduced on iOS 8)。简而言之,这真的不是你可以用正则表达式处理好的。
    • 看起来任何字符后跟: 也匹配(A:~:H: 等)。不要认为那是你想要的。在一组重复的表情符号((:(:(:(::);):))中,除了最后一个之外,所有的都错过了。
    【解决方案4】:

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

    那么你的正则表达式就会变成

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-09
      • 1970-01-01
      • 2013-07-08
      • 2019-03-30
      • 2011-05-01
      相关资源
      最近更新 更多