正则表达式匹配适用于正则表达式测试器但不适用于 oracle

Regex matching works on regex tester but not in oracle

我有正则表达式 \bname[^a-zA-Z]+[0-9]+。此正则表达式适用于 https://regexr.com/ 但不适用于 oracle。我想要的模式是: <exact word "name" (upper or lower case)><any character/s that is a non-alphabet (including line breaks) or it can be no character><a whole number>

我的测试样本在哪里:

name8213

name:1232

name: 234

name 
1231

name: 
985

name:, 123

-- Should not match any of the below text

nameis1233

name is 123

ornaments are cool 360

nickname 1323

name 1234 1233 (should not match the second set of numbers)

然而,当我执行

SELECT REGEXP_SUBSTR('name 123', '\bname[^a-zA-Z]+[0-9]+', 1, 1, 'i') FROM DUAL

我什么也没弄出来。我的最终目标是提取那个整数。

Oracle 正则表达式不支持单词边界。

在这种情况下,您需要做三件事:

  • 使用(\W|^)作为前导词边界构造替代和
  • 用另一个捕获组将您需要作为 return 获取的正则表达式部分包装起来,然后使用 REGEXP_SUBSTR 函数的正确参数获取它
  • [^a-zA-Z]+ 替换为 \W*(或 [^[:alnum:]]*,如果允许在此处使用下划线),因为您的目的是匹配 namename 之间的任何非单词字符一个数字,并且所有匹配它们之间的字母和数字都失败。

您可以使用

SELECT REGEXP_SUBSTR('name 123', '(\W|^)(name\W*[0-9]+)', 1, 1, 'i', 2) FROM DUAL

最后一个参数 2 告诉 REGEXP_SUBSTR 获取第二个捕获组的值。

详情:

  • (\W|^) - 第 1 组:非单词字符(字母、数字或下划线以外的任何字符)或字符串开头
  • (name\W*[0-9]+) - 第 2 组:name,然后是任何零个或多个非单词字符(或者任何零个或多个非字母数字字符,如果您使用 [^[:alnum:]]*)然后一个或多个数字。

Oracle 不支持正则表达式中的单词边界\b

SELECT value,
       REGEXP_SUBSTR(value, '(\W|^)(name[^a-zA-Z]*?\d+)', 1, 1, 'n', 2) AS match
FROM   table_name;

其中,对于示例数据:

CREATE TABLE table_name (value) AS
SELECT 'name8213' FROM DUAL UNION ALL
SELECT 'name:1232' FROM DUAL UNION ALL
SELECT 'name: 234' FROM DUAL UNION ALL
SELECT 'name 
1231' FROM DUAL UNION ALL
SELECT 'name: 
985' FROM DUAL UNION ALL
SELECT 'name:, 123' FROM DUAL UNION ALL
SELECT 'nameis1233' FROM DUAL UNION ALL
SELECT 'name is 123' FROM DUAL UNION ALL
SELECT 'ornaments are cool 360' FROM DUAL UNION ALL
SELECT 'nickname 1323' FROM DUAL UNION ALL
SELECT 'name 1234 1233' FROM DUAL;

输出:

VALUE MATCH
name8213 name8213
name:1232 name:1232
name: 234 name: 234
name
1231
name
1231
name:
985
name:
985
name:, 123 name:, 123
nameis1233
name is 123
ornaments are cool 360
nickname 1323
name 1234 1233 name 1234

db<>fiddle here