替换oracle中的多个特殊字符
Replacing multiple special characters in oracle
我有一个要求在oracle中替换列数据第一个和最后一个位置的特殊字符。
要求: 仅允许 [][.,$'*&!%^{}-?]
和字母数字字符保留在地址数据中,其余字符必须替换为 space.I以不同的概率尝试了以下方式,但它没有按预期工作。请帮我解决这个问题。
SELECT emp_address,
REGEXP_REPLACE(
emp_address,
'^[^[[][.,$'\*&!%^{}-?\]]]|[^[[][.,$'\*&!%^{}-?\]]]$'
) AS simplified_emp_address
FROM table_name
根据 regular expression operators and metasymbols documentation:
- 把
]
作为(取反)字符组的第一个字符;
-
作为最后;和
- 不要把
.
紧跟在[
之后,否则它可以作为联盟元素[..]
的开始匹配,如果后面有第二个.
表达式.
还有:
- 将单引号加倍(以转义它,因此它不会终止字符串文字);和
- 在捕获组中也包含 non-special 个字符
a-zA-Z0-9
否则它们将被匹配。
这给你正则表达式:
SELECT emp_address,
REGEXP_REPLACE(
emp_address,
'^[^][,.$''\*&!%^{}?a-zA-Z0-9-]|[^][,.$''\*&!%^{}?a-zA-Z0-9-]$'
) AS simplified_emp_address
FROM table_name
其中,对于示例数据:
CREATE TABLE table_name (emp_address) AS
SELECT '"test1"' FROM DUAL UNION ALL
SELECT '$test2$' FROM DUAL UNION ALL
SELECT '[test3]' FROM DUAL UNION ALL
SELECT 'test4' FROM DUAL UNION ALL
SELECT '|test5|' FROM DUAL;
输出:
EMP_ADDRESS
SIMPLIFIED_EMP_ADDRESS
"test1"
test1
$test2$
$test2$
[test3]
[test3]
test4
test4
|test5|
test5
db<>fiddle here
您不需要正则表达式,因为它们会有繁琐的转义序列。使用子字符串和 translate
函数:
with a as (
select
'some [data ]' as val
from dual
union all
select '{test $' from dual
union all
select 'clean $%&* value' from dual
union all
select 's' from dual
)
select
translate(substr(val, 1, 1), q'{ [][.,$'*&!%^{}-?]}', ' ')
|| substr(val, 2, lengthc(val) - 2)
|| case
when lengthc(val) > 1
then translate(substr(val, -1), q'{ [][.,$'*&!%^{}-?]}', ' ')
end
as value_replaced
from a
| VALUE_REPLACED |
| :--------------- |
| some [data |
| test |
| clean $%&* value |
| s |
db<>fiddle here
我有一个要求在oracle中替换列数据第一个和最后一个位置的特殊字符。
要求: 仅允许 [][.,$'*&!%^{}-?]
和字母数字字符保留在地址数据中,其余字符必须替换为 space.I以不同的概率尝试了以下方式,但它没有按预期工作。请帮我解决这个问题。
SELECT emp_address,
REGEXP_REPLACE(
emp_address,
'^[^[[][.,$'\*&!%^{}-?\]]]|[^[[][.,$'\*&!%^{}-?\]]]$'
) AS simplified_emp_address
FROM table_name
根据 regular expression operators and metasymbols documentation:
- 把
]
作为(取反)字符组的第一个字符; -
作为最后;和- 不要把
.
紧跟在[
之后,否则它可以作为联盟元素[..]
的开始匹配,如果后面有第二个.
表达式.
还有:
- 将单引号加倍(以转义它,因此它不会终止字符串文字);和
- 在捕获组中也包含 non-special 个字符
a-zA-Z0-9
否则它们将被匹配。
这给你正则表达式:
SELECT emp_address,
REGEXP_REPLACE(
emp_address,
'^[^][,.$''\*&!%^{}?a-zA-Z0-9-]|[^][,.$''\*&!%^{}?a-zA-Z0-9-]$'
) AS simplified_emp_address
FROM table_name
其中,对于示例数据:
CREATE TABLE table_name (emp_address) AS
SELECT '"test1"' FROM DUAL UNION ALL
SELECT '$test2$' FROM DUAL UNION ALL
SELECT '[test3]' FROM DUAL UNION ALL
SELECT 'test4' FROM DUAL UNION ALL
SELECT '|test5|' FROM DUAL;
输出:
EMP_ADDRESS SIMPLIFIED_EMP_ADDRESS "test1" test1 $test2$ $test2$ [test3] [test3] test4 test4 |test5| test5
db<>fiddle here
您不需要正则表达式,因为它们会有繁琐的转义序列。使用子字符串和 translate
函数:
with a as ( select 'some [data ]' as val from dual union all select '{test $' from dual union all select 'clean $%&* value' from dual union all select 's' from dual ) select translate(substr(val, 1, 1), q'{ [][.,$'*&!%^{}-?]}', ' ') || substr(val, 2, lengthc(val) - 2) || case when lengthc(val) > 1 then translate(substr(val, -1), q'{ [][.,$'*&!%^{}-?]}', ' ') end as value_replaced from a
| VALUE_REPLACED | | :--------------- | | some [data | | test | | clean $%&* value | | s |
db<>fiddle here