您的 LIKE 查询:
full_name ilike '%(first|last)%(last|first)%'
不起作用,因为 LIKE 不理解正则表达式分组 ((...)) 或交替 (|),LIKE 仅理解单个字符的 _(如正则表达式中的 .)和% 用于任何零个或多个字符的序列(如正则表达式中的 .*)。
如果您将该模式交给 SIMILAR TO,那么您会找到 'first last',但由于案例问题,其他的都找不到;但是,这个:
lower(full_name) similar to '%(first|last)%(last|first)%'
将处理案例问题并找到与您的正则表达式相同的问题。
如果您想使用正则表达式(您可能会这样做,因为 LIKE 非常有限且繁琐,而且 SIMILAR TO 是一些 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