我尝试提取'''来自' EM 930'使用以下Regexp
REGEXP_REPLACE(info,'^[:space:]*[ABCDEFGHIJKLMNOPQRSTUVWXYZ]*[:space:]*([0-9]+)[:space:]*$','\1')
但它返回原始字符串。 一个想法为什么?
附属问题: 为什么" \ 1"当模式不匹配时返回原始字符串?我希望它返回NULL,就像在我的其他正则表达式体验中一样(例如Perl)。
我能以高效的方式重新编写这个内容,这样我才能得到匹配的好的NULL字符串吗?
答案 0 :(得分:2)
你的太空人物角色并不完全正确。如果我们将[:space:]
更改为[[:space:]]
,您的regexp_replace将按预期运行:
REGEXP_REPLACE(info, '^[[:space:]]*[ABCDEFGHIJKLMNOPQRSTUVWXYZ]*[[:space:]]*([0-9]+)[[:space:]]*$','\1')
为了简洁起见,我们可以使用上部字符类[[:upper:]]
作为[ABCDEFGHIJKLMNOPQRSTUVWXYZ]
。这会将函数调用更改为:
regexp_replace(info, '^[[:space:]]*[[:upper:]]*[[:space:]]*([0-9]+)[[:space:]]*$','\1')
或者可以使用转义字符代替字符类:
\s
空间
\w
字符
\d
数字字符
regexp_replace(info, '^\s*\w*\s*(\d+)\s*$','\1')
说明:
由于格式错误的字符类[:space:]
与“' EM'之间存在的空间不匹配和' 930',您按参数搜索与source参数中的任何字符都不匹配。
您按参数'^[[:space:]]*[ABCDEFGHIJKLMNOPQRSTUVWXYZ]*[[:space:]]*([0-9]+)[[:space:]]*$'
进行搜索会锚定到列的开头和结尾,因此它只能匹配列,信息,最多只能匹配一次。
在您的情况下,没有匹配项,与'\1'
关联的字符组'([0-9]*)'
没有值。
因此,不会替换任何字符,并保留列{info,'EM 930'
的原始值。
有趣的变体可以更好地理解这个功能:
- 如果您更正的函数调用没有pattern_to_replace_by参数'\1'
,那么将返回NULL:
regexp_replace(info,' ^ \ s * \ w * \ s *(\ d +)\ s * $')FROM dual;
- 由于你有一个pattern_to_replace_by参数,'\1'
,现在它有匹配的字符组,会返回重复的数字组:
930