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 正则表达式验证

我可以在 PL/SQL 块中使用 REGEXP_LIKE 作为 IF 的条件吗

PL/SQL:字符串的 regexp_like 不以字母开头

SQL 基础正则表达式(二十三)

PL/SQL:通过正则表达式查找所有西里尔文(或非拉丁文)符号

Oracle 正则表达式函数-REGEXP_LIKE 使用例子