ruby-on-rails - 当正则表达式具有不同的字节表示时如何匹配元音变音符 (äöü)?

标签 ruby-on-rails regex ruby

所以我有一个奇怪的问题。我在 S3 上有文件,我想使用正则表达式将单词与文件名进行匹配。正则表达式应该清楚地匹配,但它没有:

irb(main):048:0> p.original_filename
=> "Küche.png"
irb(main):049:0> "Küche.png"
=> "Küche.png"
irb(main):013:0> reg = /(\A|\W|\d|_)#{Regexp.quote("Küche")}(\W|\z|\d|_)/i
=> /(\A|\W|\d|_)Küche(\W|\z|\d|_)/i
irb(main):014:0> reg.match?("Küche.png")
=> true
irb(main):015:0> reg.match?(p.original_filename)
=> false
irb(main):050:0> p.original_filename == "Küche.png"
=> false

所以我进一步检查并假设存在编码问题:

irb(main):017:0> p.original_filename.encoding
=> #<Encoding:UTF-8>
irb(main):018:0> "Küche.png".encoding
=> #<Encoding:UTF-8>

这很奇怪。但是让我们看看表示背后的字符和字节是什么:

irb(main):025:0> "Küche.png".chars
=> ["K", "ü", "c", "h", "e", ".", "p", "n", "g"]
irb(main):026:0> p.original_filename.chars
=> ["K", "u", "̈", "c", "h", "e", ".", "p", "n", "g"]
irb(main):032:0> p.original_filename.bytes
=> [75, 117, 204, 136, 99, 104, 101, 46, 112, 110, 103]
irb(main):033:0> "Küche.png".bytes
=> [75, 195, 188, 99, 104, 101, 46, 112, 110, 103]

那么问题来了。我的问题:如何规范化文件名,使其与正则表达式匹配 /(\A|\W|\d|_)#{Regexp.quote("Küche")}(\W|\z|\d|_)/i ?我尝试了 force_encodingencode 但没有成功,因为字节不同。

注意:不能只使用 ASCII 字符作为文件名。这必须与元音一起使用。

最佳答案

在 Unicode 中,某些字符可以表示为基本字符和组合字符:

"\u0075\u0308" # LATIN SMALL LETTER U (U+0075) + COMBINING DIAERESIS (U+0308)
#=> "ü"

或作为单个预组合字符:

"\u00fc"       # LATIN SMALL LETTER U WITH DIAERESIS (U+00FC)
#=> "ü"

如果您在键盘上键入字符,它通常会生成后者。

将给定字符串转换为这些表示之一的过程称为规范化

在 Ruby 中,有 String#unicode_normalize默认为后一种格式:

a = "\u0075\u0308"
b = "\u00fc"

a.codepoints                   #=> [117, 776]
b.codepoints                   #=> [252]
a.unicode_normalize.codepoints #=> [252]

应用于您的示例,您将使用:

reg.match?(p.original_filename.unicode_normalize)

关于ruby-on-rails - 当正则表达式具有不同的字节表示时如何匹配元音变音符 (äöü)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59308479/

相关文章:

ruby-on-rails - 在 Ruby on Rails 中,如何为 ActiveRecord 对象的 member_of 成员分配默认值?

ruby-on-rails - 指定要与 git merge 的文件夹

ruby-on-rails - 在 Rails 模型中使用数组作为数据类型时,在表单字段中我得到空大括号 `{}`

ruby-on-rails - 如何在 Rails 开发中忽略延迟作业查询日志记录

ruby-on-rails - seed.rb 中的关联

regex - 如何为 less 命令正确编写正则表达式模式

regex - 使用 REGEXP_EXTRACT 没有给出预期的结果 - Hive

regex - 避免使用正则表达式的 Twitter 配置文件名称 (@Profile)

ruby-on-rails - 如何将变量名与图像标签一起使用

ruby - 在 Ruby 中使用 return 不是惯用的吗?