我會跳過相似並直行到POSIX regexes,我敢肯定SIMILAR TO將被轉換爲正則表達式內部何必呢?此外,~
將讓您使用ANY
產生一個很好的可讀表達式。你可以做這樣的事情:
str = 'some string, some other string, final string'
items = Item.where('item_name ~ any(array[?])', str.split(/\s*,\s*/))
這最終將運行SQL這樣的:
select "items".* from "items" where item_name ~ any(array['some string', 'some other string', 'final string'])
,這將產生相同的結果作爲相似到版本不扯皮一串字符串。
如果你面對的是一個可以包含正則表達式元字符的CSV字符串,那麼你可能希望在混合中引入一些轉義。 Backslashing任何非字母數字應該是足夠安全:
str = 'some string, some other string, final string'
pats = str.split(/\s*,\s*/)
.map { |s| s.gsub(/\p{^Alnum}/) { '\\' + $& } }
items = Item.where('item_name ~ any(array[?])', pats)
切換到LIKE也是一種選擇,那麼你只需要擔心_
和%
:
str = 'some string, some other string, final string'
pats = str.split(/\s*,\s*/)
.map { |s| s.gsub(/[_%]/, '%' => '\\%', '_' => '\\_') }
.map { |s| '%' + s + '%' }
items = Item.where('item_name like any(array[?])', pats)
在現實生活中您可以將實用程序方法中的逃逸亂七八糟(以及「添加LIKE百分號」混亂)變得更清晰。
如果您不關心case,那麼您可以使用~*
或ilike
進行不區分大小寫的模式匹配。
'海峽= 「一些字符串,其他一些字符串,最後一個字符串」 .split( ''){地圖|。S | 「%(#{s.strip})%」}'然後'相對於任何(ARRAY#{str})'可能工作嗎? – j03w
@ j03w:我無法與SIMILAR TO一起工作,因此我認爲你會陷入LIKE或跳到真正的正則表達式。 –