Postgresql和ActiveRecord在哪里:正则表达式匹配

时间:2014-04-02 00:56:15

标签: ruby-on-rails regex postgresql activerecord rails-activerecord

我在普通正则表达式中创建了这个正则表达式

/(first|last)\s(last|first)/i

它匹配前三个

first last
Last first
First Last
First name

我正在尝试获取full_name与我编写的正则表达式匹配的所有记录。我正在使用PostgreSQL

Person.where("full_name ILIKE ?", "%(first|last)%(last|first)%")

这是我的尝试。我还尝试了SIMILAR TO~没有运气

1 个答案:

答案 0 :(得分:39)

您的LIKE查询:

full_name ilike '%(first|last)%(last|first)%'

不起作用,因为LIKE不理解正则表达式分组((...))或替换(|),LIKE只能理解单个字符的_(如正则表达式中的.%任意零个或多个字符的序列(如正则表达式中的.*)。

如果您将该模式交给SIMILAR TO,那么您会发现'first last',但由于案例问题,其他人都没有;但是,这个:

lower(full_name) similar to '%(first|last)%(last|first)%'

将处理案例问题并找到与正则表达式相同的内容。

如果你想使用一个正则表达式(你可能会这样做,因为LIKE是非常有限和繁琐的,而且类似于某些SQL标准小组委员会的狂热思想的奇怪产品)那么你会想要使用不区分大小写的匹配运算符和原始正则表达式:

full_name ~* '(first|last)\s+(last|first)'

这转化为AR的这一点:

Person.where('full_name ~* :pat', :pat => '(first|last)\s+(last|first)')
# or this
Person.where('full_name ~* ?', '(first|last)\s+(last|first)')

我的代码中有一个微妙的变化需要注意:我使用单引号作为我的Ruby字符串,你使用的是双引号。反斜杠在双引号字符串中比在单引号字符串中表示更多,因此'\s'"\s"是不同的东西。抛出几个to_sql电话,你可能会看到一些有趣的东西:

> puts Person.where('full_name ~* :pat', :pat => 'a\s+b').to_sql
SELECT "people".* FROM "people"  WHERE (full_name ~* 'a\s+b')

> puts Person.where('full_name ~* :pat', :pat => "a\s+b").to_sql
SELECT "people".* FROM "people"  WHERE (full_name ~* 'a +b')

这种差异可能不会导致任何问题,但是当每个人都想使用相同的转义字符时,你需要非常小心你的字符串。就个人而言,我使用单引号字符串,除非我特别需要双引号字符串的额外转义和字符串插值功能。

一些演示:http://sqlfiddle.com/#!15/99a2c/6