44

我正在尝试搜索 A0001、A0002、A1234、A2351 等系列中的最大数字...问题是我正在搜索的列表中也有字符串,例如 AG108939、E092357、AL399、22-30597 , ETC...

所以基本上,我想要我的数据库中的最高 A#### 值。我正在使用以下查询:

@max_draw = Drawing.where("drawing_number LIKE ?", "A%")

这一直有效,直到像 AG309 这样的数字开始妨碍它,因为它以 A 开头,但格式与我正在寻找的格式不同。

我假设这对于正则表达式应该非常简单,但我是新手,不知道如何用正则表达式正确编写这个查询。以下是我尝试过的一些只返回 nil 的方法:

 @max_draw = Drawing.where("drawing_number LIKE ?", /A\d+/)
 @max_draw = Drawing.where("drawing_number LIKE ?", "/A\d+/")
 @max_draw = Drawing.where("drawing_number LIKE ?", "A[0-9]%")
4

3 回答 3

80

在带有 Postgres 数据库的 Rails 4+ 上,RegEx 查询的一般形式是:

Model.where("column ~* ?", 'regex')

至于正则表达式,它可以是一般'^A\d+$'或更具体的'^A\d{4}$' 分解:

^ - string start anchor
A - literal "A"
\d+ - one or more digits (0-9)
\d{4} - exactly four digits
$ - string end anchor

基本上,正则表达式读取“字符串应以 A 开头,后跟四位数字,然后字符串应结束”。最后的查询行是:

@max_draw = Drawing.where("drawing_number ~* ?", '^A\d{4}$')

进一步阅读RubyDoc上的 ruby​​ RegEx或更易于访问的Perl 变体(由 Sublime 文本使用)

于 2014-10-27T12:47:03.017 回答
32

你做得好!缺少的是REGEXP在查询中用于正则表达式的函数:

所以在你的情况下使用

Drawing.where("drawing_number REGEXP ?", 'A\d{4}')
# the {4} defines that there have to be exactly 4 numbers, change if you need to

在 SQL 中,您使用'-colons,这很奇怪,因为您通常使用 regex/-backslashes

于 2013-11-04T21:55:51.240 回答
-3

您不能在 SQL 中使用正则表达式,这是您正在尝试做的。您最好的选择是只选择以 A 开头的条目,就像您的原始代码一样,然后跳过开头有多个字母的条目。

items = Drawing.where( [ 'drawing_number LIKE ?' , 'A%' ] )
max_value = 0
items.each do |item|
  next if item.drawing_number =~ /\A[A-Za-z]{2,}/
  drawing_number = item.drawing_number.gsub(/\AA/, '').to_i
  max_value = drawing_number if drawing_number > max_value
end

我有理由确定可以缩短此时间,但这应该可以满足您的需要。

(\A 是行锚的开始,适用于包含换行符的字符串)

({2,} 匹配两个或多个前面的字符范围)

http://www.rubular.com/非常适合测试 ruby​​ 正则表达式。

于 2013-11-04T21:55:35.727 回答