PL / SQL. Синтаксический анализ UTF8-символов с регулярными выражениями регулярного выражения - PullRequest
0 голосов
/ 08 мая 2018

Я хочу проверить, есть ли в какой-либо строке моего саба странные символы, такие как (±). Эти символы читаются из csv-файла с неожиданной кодировкой (UTF-8), которая преобразует некоторые из них.

Я попытался отфильтровать каждую строку с помощью регулярного выражения, но он не работает, как предполагалось. Есть ли способ узнать кодировку csv-файла при чтении?

Как я могу исправить регулярное выражение, чтобы разрешить строки только с этими символами? a-zA-Z 0-9 .,;:"'()-_& пробел.

Пример Clob, полученный из csv:

  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;

1 Ответ

0 голосов
/ 08 мая 2018

Если вы хотите разрешить только специальные символы, вы можете использовать это регулярное выражение:

Ваше регулярное выражение

csvregexp   CONSTANT VARCHAR2 (1000) := '^[a-zA-Z 0-9 .,;:"''()-_&]+$' ;

Regex-подробности

  • ^ Начало вашей строки - без символов до этого - предотвращает частичное совпадение
  • [] набор разрешенных символов
  • []+ набор разрешенных символов. Должен быть минимум один символ до инф. (* вместо + будет означать 0-инф.)
  • [a-zA-Z]+ 1 до инф. письма
  • [a-zA-Z0-9]+ 1 до инф. буквы и цифры
  • $ конец вашей строки - без символов после этого - предотвращает частичное совпадение

Думаю, с этим можно разобраться; -)

Если вы знаете, что в вашем входе может быть другая кодировка, вы можете попробовать преобразовать и снова проверить соответствие регулярному выражению.

Пример-преобразование * * 1 032 select convert('täst','us7ascii', 'utf8') from dual;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...