【问题标题】:Test column for special characters or only characters / numbers特殊字符或仅字符/数字的测试列
【发布时间】:2019-09-25 13:16:22
【问题描述】:

我尝试使用通用正则表达式属性和NOT LIKE 子句查找特殊字符,但得到的结果令人困惑。研究表明,它的工作方式与在 SQL Server 或其他地方的工作方式不同。

  1. 用于查找是否有字符
  2. 用于查找是否有任何数字
  3. 用于查找是否有任何特殊字符

like '%[^0-9]%''%[^a-Z]%' 分别在查找是否存在非数字数据和是否存在非字母数据时效果不佳

SELECT column1 from some_table where column1 like '%[^0-9]%'; 
SELECT column1 from some_table where column1 like '%[^a-Z]%' 
SELECT column1 from some_table where column1 like '%[^a-Z0-9]%' 

还注意到人们使用 -> NOT like '%[^0-9]%'

【问题讨论】:

  • LIKE 不支持 SQL 中的正则表达式

标签: sql regex postgresql data-cleaning


【解决方案1】:

问题是您错误地使用了LIKELIKE 无法识别这些模式。

使用~进行正则表达式匹配:

select column1 from some_table where column1 ~ '[^a-Z0-9]' 

或更恰当地说:

select column1 from some_table where column1 ~ '[^a-zA-Z0-9]'

这将返回具有未在字符类中指定的字符的任何列。

Here 是一个 dbfiddle。

【讨论】:

  • 这对我不起作用。我尝试了 ~ '[^a-Z]' 来确定我是否可以获得非字符值,但它只是给了我不以 'a' 或 'Z' 开头的城市的名称。有什么想法吗?
  • @VishwalShah 。 . .正则表达式匹配名称中任何位置包含任何非字母的城市名称。我会假设它只是碰巧首先返回以不同字符开头的城市名称。
  • 它应该返回非基于字母的记录,但它只是显示干净的基于字母的记录。您的假设可能是正确的,但它仍然没有向我显示任何非字母记录
【解决方案2】:

Postgres LIKE 不支持正则表达式。
你需要regular expression operator ~

标准 SQL 还将 SIMILAR TO 定义为上述的奇怪组合,但不要使用它。见:

用于查找是否有任何字符

...意思是任何字符

... WHERE col <> '';                        -- any character at all?

所以既不是 NULL 也不是空的。见:

...表示任何字母字符(字母):

... WHERE col ~ '[[:alpha:]]';              -- any letters?

[[:alpha:]] 是所有字母字符的字符类 - 不仅仅是 ASCII 字母 [A-Za-z],还包括 [ÄéÒçòý] 等字母。

用于查找是否有任何数字

...表示任何数字

... WHERE col ~ '\d';                       -- any digits?

\d[[:digit:]] 的类简写。

用于查找是否有特殊字符

...除了数字和字母之外的任何含义:

... WHERE col ~ '\W';                       -- anything but digits & letters? 

\W[^[:alnum:]_] 的类简写(下划线已排除 - 手册目前在此处令人困惑)。

...表示除数字、字母和纯空格以外的任何内容:

... WHERE col ~ '[^[:alnum:]_ ]'            -- ... and space

这是\W 拼写出来的类简写,另外不包括纯空格。

...表示除数字、字母和任何空格之外的任何内容:

... WHERE col ~ '[^[:alnum:]_\s]'           -- ... and any white space
... WHERE col ~ '[^[:alnum:]_[:space:]]'    -- ... the same spelled out

这次不包括由 Posix 字符类 space 定义的所有空格。关于 Unicode 中的“空白”:

... 表示任何非 ASCII 字符:

如果您的数据库集群使用 UTF8 编码运行,则有一个简单、非常快速的 hack:

... WHERE octet_length(col) > length(col);  -- any non-ASCII letter?

octet_length()计算字符串中的字节,而length()(别名:character_length()char_length())计算字符串中的字符。所有基本 ASCII 字符 ([\x00-\x7F]) 在 UTF-8 中使用 1 个字节编码,所有其他字符使用 2 - 4 个字节。字符串中的任何非 ASCII 字符都构成表达式 true

进一步阅读:

【讨论】:

  • 工作就像一个魅力!非常感谢你付出的努力。 ... WHERE column1 ~ '\W';有效,但它也显示带有空格的记录。为此,我使用了 AND like '% %'; ('% %' 之间有 )。这消除了有空格的记录,并给了我有特殊字符的记录结果
  • 我添加了一些额外处理空白。
猜你喜欢
  • 1970-01-01
  • 2011-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-11
  • 1970-01-01
相关资源
最近更新 更多