首页 > 解决方案 > 检查字符串是否包含 Ruby 中的表情符号

问题描述

在 ruby​​ 中,您可以通过以下方式检查字符串中的子字符串:

str = "hello world"
str.include?("lo")
=> true

当我尝试在 rails 应用程序的文本列中保存表情符号时(mysql 数据库中的文本列是utf8),它返回此错误:

不正确的字符串值:\xF0\x9F\x99\x82

对于我在 Rails 应用程序中的情况,只需查看提交的文本中是否存在表情符号即可。如果存在表情符号:引发验证错误。例子:

class MyModel < ApplicationRecord
  validate :cannot_contain_emojis

  private

  def cannot_contain_emojis
    if my_column.include?("/\xF0")
      errors.add(:my_column, 'Cannot include emojis")
    end 
  end
end

注意:我检查的原因\xF0是因为根据这个网站,似乎所有或大多数表情符号都以这个签名开头。

然而,这不起作用。false即使它是真的,它也会继续返回。我很确定问题是我的 include 语句不起作用,因为表情符号没有转换为字节进行比较。

问题 如何进行验证以检查表情符号是否未传入?

标签: ruby-on-railsruby

解决方案


您可以使用EmojiUnicode 属性来使用 测试表情符号Regexp,如下所示:

def cannot_contain_emojis
  if /\p{Emoji}/ =~ my_column
    errors.add(:my_column, 'Cannot include emojis')
  end 
end

Unicode® Technical Standard #51 "UNICODE EMOJI"包含更复杂的正则表达式

\p{RI} \p{RI} 
| \p{Emoji} 
  ( \p{EMod} 
  | \x{FE0F} \x{20E3}? 
  | [\x{E0020}-\x{E007E}]+ \x{E007F} )?
  (\x{200D} \p{Emoji}
    ( \p{EMod} 
    | \x{FE0F} \x{20E3}? 
    | [\x{E0020}-\x{E007E}]+ \x{E007F} )?
  )*

[注意:其中一些属性未在 Onigmo / Ruby 中实现。]

但是,检查表情符号可能还不够。很明显,您的文本处理在某些时候被破坏了。如果它被一个 Emoji 打破,那么它也有可能被我的名字打破,或者 Ruby 的创造者松本行弘的名字,或者完全正常的英文单词“naïve”。

与其玩打地鼠游戏,试图检测每个表情符号、数学符号、阿拉伯字母、印刷正确的标点符号等,不如简单地修复文本处理。


推荐阅读