PL/SQL。使用 regexp_like 正则表达式解析 clob UTF8 字符
Posted
技术标签:
【中文标题】PL/SQL。使用 regexp_like 正则表达式解析 clob UTF8 字符【英文标题】:PL/SQL. Parse clob UTF8 chars with regexp_like regular expressions 【发布时间】:2018-05-08 11:01:18 【问题描述】:我想检查我的 clob 的任何一行是否有奇怪的字符,如 (ñ§)。这些字符是从具有意外编码 (UTF-8) 的 csv 文件中读取的,该编码转换了其中的一些字符。
我尝试使用正则表达式过滤每一行,但它没有按预期工作。有没有办法在读取时知道 csv 文件的编码?
如何修复正则表达式以允许仅包含这些字符的行? a-zA-Z 0-9 .,;:"'()-_&
空格制表符。
从 csv 读取的 Clob 示例:
l_clob clob :='
"exp","objc","objc","OBR","031110-5","S","EXAMPLE","NAME","08/03/2018",,"122","3","12,45"
"xp","objc","obj","OBR","031300-5","S","EXAMPLE","NAME","08/03/2018",,"0","0","0"
';
另一个笨蛋:
DECLARE
l_clob CLOB
:= '"exp","objc","objc","OBR","031110-5","S","EXAMPLE","NAME","08/03/2018",,"122","3","12,45"
"xp","objc","obj","OBR","031300-5","S","EXAMPLE","NAME","08/03/2018",,"0","0","0"';
l_offset PLS_INTEGER := 1;
l_line VARCHAR2 (32767);
csvregexp CONSTANT VARCHAR2 (1000)
:= '^([''"]+[-&\s(a-z0-9)]*[''"]+[,:;\t\s]?)?[''"]+[-&\s(a-z0-9)]*[''"]+' ;
l_total_length PLS_INTEGER := LENGTH (l_clob);
l_line_length PLS_INTEGER;
BEGIN
WHILE l_offset <= l_total_length
LOOP
l_line_length := INSTR (l_clob, CHR (10), l_offset) - l_offset;
IF l_line_length < 0
THEN
l_line_length := l_total_length + 1 - l_offset;
END IF;
l_line := SUBSTR (l_clob, l_offset, l_line_length);
IF REGEXP_LIKE (l_line, csvregexp, 'i')
THEN -- i (case insensitive matches)
DBMS_OUTPUT.put_line ('Ok');
DBMS_OUTPUT.put_line (l_line);
ELSE
DBMS_OUTPUT.put_line ('Error');
DBMS_OUTPUT.put_line (l_line);
END IF;
l_offset := l_offset + l_line_length + 1;
END LOOP;
END;
【问题讨论】:
一个只允许 ASCII 的简单正则表达式是^[ -~]*$
【参考方案1】:
如果你只想允许特殊字符,你可以使用这个正则表达式:
你的正则表达式
csvregexp CONSTANT VARCHAR2 (1000) := '^[a-zA-Z 0-9 .,;:"''()-_&]+$' ;
正则表达式详细信息
^
字符串的开头 - 在此之前没有字符 - 防止部分匹配
[]
一组允许的字符
[]+
一组允许的字符。必须至少为一个字符,直到 inf。 (* 而不是 + 表示 0-inf。)
[a-zA-Z]+
1 到 inf。字母
[a-zA-Z0-9]+
1 到 inf。字母和数字
$
字符串结尾 - 后面没有字符 - 防止部分匹配
我认为你可以解决这个问题 ;-)
如果您知道输入中可能存在其他编码,则可以尝试转换并再次检查正则表达式。
示例-转换
select convert('täst','us7ascii', 'utf8') from dual;
【讨论】:
谢谢,但输入文件中的编码可能太多,所以即使某些字符错误,我也会使用类似的正则表达式进行过滤。以上是关于PL/SQL。使用 regexp_like 正则表达式解析 clob UTF8 字符的主要内容,如果未能解决你的问题,请参考以下文章
我可以在 PL/SQL 块中使用 REGEXP_LIKE 作为 IF 的条件吗
PL/SQL:字符串的 regexp_like 不以字母开头