带有 Concat 的 MariaDB 正则表达式只能捕获一些结果
MariaDB regex with Concat only catches some results
我有一个 table 的 VARCHAR 列,我需要检查它的值:
典型数据值为:
Brize Norton (501, 622, 2624, 4624, 4626)
Wyton (7006, 7010, 7630)
Waddington (2503, 7006)
Honington (2623)
Marham (2620, 7010)
Leeming (607 & 609)
我唯一需要检查的部分是它只包含完整的数字。我无法检查 只是 的数字,因为 LIKE '%607%'
也会错误地匹配 6070
或 2607
,所以我检查了包装的数量和变体所以:
我有这个查询:
SELECT id, name FROM aux WHERE aux.name REGEXP CONCAT('[(,\h]',:num, '[),\h]')
这是为了捕获 VARCHAR 列中的任何(( or, or <whitespace>
、a variable number value
、) or , or <whitespace>
)。
这对某些数字有效,但对其他数字无效;
一个例子:
:num = 2620
SELECT id, name FROM aux WHERE aux.name REGEXP CONCAT('[(,\h]',:num, '[),\h]')
结果:
"Marham (2620, 7010)"
但在其他号码上失败:
:num = 7010
SELECT id, name FROM aux WHERE aux.name REGEXP CONCAT('[(,\h]',:num, '[),\h]')
结果:
(Nothing)
我如何告诉 REGEXP 捕获如上 ( or, or <whitespace>
、a variable number value
、) or , or <whitespace>
.
形状的数据
我已经尝试 EXPLAIN
我的查询,但这并不能帮助我了解 REGEXP 机制。
我已经用 \s
替换了 \h
但这没有什么区别。
您的 MariabDB 不支持 PCRE 正则表达式语法,因此只能使用符合 POSIX 的正则表达式。 \h
和 \s
都不符合 POSIX,在 POSIX 世界中,\h
与 [:blank:]
和 \s
是“等价的” [:space:]
.
更多POSIX/PCRE字符class等效模式:
POSIX Character Class
PCRE
Description
[:alnum:]
[:alnum:]
/ [\p{L}\p{N}]
Alphanumeric
[:alpha:]
\p{L}
Alphabetic
[:blank:]
\h
Whitespace
[:cntrl:]
[:cntrl:]
/ \p{Cc}
/ \p{C}
Control characters
[:digit:]
\d
Digits
[:graph:]
[:graph:]
Graphic characters
[:lower:]
\p{Ll}
Lowercase alphabetic
[:print:]
[:print:]
Graphic or space characters
[:punct:]
[\p{P}\p{S}]
Punctuation
[:space:]
\s
Space, tab, newline, and carriage return
[:upper:]
\p{Lu}
Uppercase alphabetic
[:xdigit:]
[:xdigit:]
/ [A-Fa-f0-9]
Hexadecimal digit
你可以使用
REGEXP CONCAT('[(,[:blank:]]', :num, '[),[:blank:]]')
REGEXP CONCAT('[(,[:space:]]', :num, '[),[:space:]]')
如果您只是想强制实施数字边界,请使用
CONCAT('([^0-9]|^)',:num, '([^0-9]|$)')
CONCAT('([^[:digit:]]|^)',:num, '([^[:digit:]]|$)')
正则表达式详细信息:
[(,[:space:]]
- (
、,
或任何空白字符
[),[:space:]]
- )
、,
或任何空白字符
[(,[:blank:]]
- (
、,
或水平空白字符
[),[:blank:]]
- )
、,
或水平空白字符
([^0-9]|^)
/ ([^[:digit:]]|^)
- 任何非数字字符或字符串开头
([^0-9]|$)
/ ([^[:digit:]]|$)
- 任何非数字字符或字符串结尾。
本质上,这是版本问题,因为 until version 10.0.5 MariaDB 使用 POSIX 1003.2 兼容的正则表达式库。该库不支持 \h
、\d
等字符 classes,使用它们的 POSIX 变体 - [:alpha:]
、[:digit:]
等.
但是,在您的情况下,您似乎可以将 \s
或 \h
替换为该字符中的单个空格 class:
REGEXP CONCAT('[(, ]', :num, '[), ]')
我有一个 table 的 VARCHAR 列,我需要检查它的值:
典型数据值为:
Brize Norton (501, 622, 2624, 4624, 4626)
Wyton (7006, 7010, 7630)
Waddington (2503, 7006)
Honington (2623)
Marham (2620, 7010)
Leeming (607 & 609)
我唯一需要检查的部分是它只包含完整的数字。我无法检查 只是 的数字,因为 LIKE '%607%'
也会错误地匹配 6070
或 2607
,所以我检查了包装的数量和变体所以:
我有这个查询:
SELECT id, name FROM aux WHERE aux.name REGEXP CONCAT('[(,\h]',:num, '[),\h]')
这是为了捕获 VARCHAR 列中的任何(( or, or <whitespace>
、a variable number value
、) or , or <whitespace>
)。
这对某些数字有效,但对其他数字无效;
一个例子:
:num = 2620
SELECT id, name FROM aux WHERE aux.name REGEXP CONCAT('[(,\h]',:num, '[),\h]')
结果:
"Marham (2620, 7010)"
但在其他号码上失败:
:num = 7010
SELECT id, name FROM aux WHERE aux.name REGEXP CONCAT('[(,\h]',:num, '[),\h]')
结果:
(Nothing)
我如何告诉 REGEXP 捕获如上 ( or, or <whitespace>
、a variable number value
、) or , or <whitespace>
.
我已经尝试 EXPLAIN
我的查询,但这并不能帮助我了解 REGEXP 机制。
我已经用 \s
替换了 \h
但这没有什么区别。
您的 MariabDB 不支持 PCRE 正则表达式语法,因此只能使用符合 POSIX 的正则表达式。 \h
和 \s
都不符合 POSIX,在 POSIX 世界中,\h
与 [:blank:]
和 \s
是“等价的” [:space:]
.
更多POSIX/PCRE字符class等效模式:
POSIX Character Class | PCRE | Description |
---|---|---|
[:alnum:] |
[:alnum:] / [\p{L}\p{N}] |
Alphanumeric |
[:alpha:] |
\p{L} |
Alphabetic |
[:blank:] |
\h |
Whitespace |
[:cntrl:] |
[:cntrl:] / \p{Cc} / \p{C} |
Control characters |
[:digit:] |
\d |
Digits |
[:graph:] |
[:graph:] |
Graphic characters |
[:lower:] |
\p{Ll} |
Lowercase alphabetic |
[:print:] |
[:print:] |
Graphic or space characters |
[:punct:] |
[\p{P}\p{S}] |
Punctuation |
[:space:] |
\s |
Space, tab, newline, and carriage return |
[:upper:] |
\p{Lu} |
Uppercase alphabetic |
[:xdigit:] |
[:xdigit:] / [A-Fa-f0-9] |
Hexadecimal digit |
你可以使用
REGEXP CONCAT('[(,[:blank:]]', :num, '[),[:blank:]]')
REGEXP CONCAT('[(,[:space:]]', :num, '[),[:space:]]')
如果您只是想强制实施数字边界,请使用
CONCAT('([^0-9]|^)',:num, '([^0-9]|$)')
CONCAT('([^[:digit:]]|^)',:num, '([^[:digit:]]|$)')
正则表达式详细信息:
[(,[:space:]]
-(
、,
或任何空白字符[),[:space:]]
-)
、,
或任何空白字符[(,[:blank:]]
-(
、,
或水平空白字符[),[:blank:]]
-)
、,
或水平空白字符([^0-9]|^)
/([^[:digit:]]|^)
- 任何非数字字符或字符串开头([^0-9]|$)
/([^[:digit:]]|$)
- 任何非数字字符或字符串结尾。
本质上,这是版本问题,因为 until version 10.0.5 MariaDB 使用 POSIX 1003.2 兼容的正则表达式库。该库不支持 \h
、\d
等字符 classes,使用它们的 POSIX 变体 - [:alpha:]
、[:digit:]
等.
但是,在您的情况下,您似乎可以将 \s
或 \h
替换为该字符中的单个空格 class:
REGEXP CONCAT('[(, ]', :num, '[), ]')