我想防止我的Client
记录在其name
或last_name
属性中包含数字或特殊字符。
我在Client
模型中设置了一个格式验证,如下所示:
validates :name,
format: { with: /\A[a-zÀ-ú\s]+\z/i, message: :wrong_format }
validates :last_name,
format: { with: /\A[a-zÀ-ú\s]+\z/i, message: :wrong_format }
据我所知,这将允许字符串包含字母字符,包括重音符号,如α(a-zÀ-ú
),加上任何白色字符(\s
),以及0个或多个该组合(+
)。
验证工作正常,防止表单提交,例如P3ter
。
**问题是:**使用相同的正则表达式查询Postgres DB以查找匹配它的记录,返回类似P3ter
的记录。当然,在查询中对该正则表达式取反以搜索do not
匹配它的记录,不会返回类似P3ter
的记录(当我有它们时)。
select * from clients
where name !~* '[a-zÀ-ú\s]+'
or last_name !~* '[a-zÀ-ú\s]+'
// no results
我尝试了一个不同的正则表达式,比如[[:alpha:][:space:]]+
,它在表单验证中同样获得了令人满意的结果,但在DB查询中使用时却得到了同样奇怪的结果。
为什么正则表达式用于格式验证,以防止表单提交带有P3ter
之类的字符串,但在查询中使用时,同一个正则表达式返回P3ter
之类的记录?
1条答案
按热度按时间63lcw9qa1#
问题是:
你没有在正则表达式模式的开头加上
^
,在结尾加上$
。正则表达式模式[a-zÀ-ú\s]+
匹配P3ter
的ter
。^
匹配每行的开始。而$
匹配每行的结尾。[a-zÀ-ú\s]
这意味着仅匹配从a
到z
或从À
到ú
或\s
的一个字符,该字符是空白字符(相当于[\r\n\t\f\v ]
)。[a-zÀ-ú\s]+
此部分匹配P3ter
的ter
。+
符号表示在一次到无限次之间匹配前面的令牌,基本上表示匹配一个或多个,至少匹配一个字符。解决方案: