Разделить строку, используя REGEXP_SUBSTR SQL - PullRequest
0 голосов
/ 28 мая 2020

Мне нужно разделить такую ​​строку

RANDOM(NUL)THIS_SHOULD_BE_SPLIT(NUL)~THIS_IS_NEW(NUL)STRING(NUL)~THIS_IS_ANOTHER_STRING(NUL)

(NUL) означает символ со значением ASCII 0. Не знаю, как это ввести здесь.

Мне нужно разделить это, когда происходит (NUL)~.

Таким образом, ожидаемый результат после разделения будет

  1. RANDOM(NUL)THIS_SHOULD_BE_SPLIT
  2. THIS_IS_NEW(NUL)STRING
  3. THIS_IS_ANOTHER_STRING(NUL)

Используя OracleDB, вы не знаете, как он обрабатывает символы NULL и возможно ли их разделить.

Чтобы разделить его с помощью ~, я использую

SELECT REGEXP_SUBSTR(stringval,'[^~]+', 1, LEVEL) AS error_code
FROM   DUAL
CONNECT BY REGEXP_SUBSTR(stringval, '[^~]+',1,LEVEL) IS NOT NULL;

Не знаю, как включить сюда символ NULL.

Ответы [ 2 ]

1 голос
/ 28 мая 2020

Вы не можете напрямую сопоставить символ ASCII 0 (NUL) в регулярном выражении, поскольку синтаксический анализатор регулярных выражений будет рассматривать символ ASCII 0 (NULL) как терминатор строки и завершать шаблон регулярного выражения , а не использовать его как символ для соответствия. Итак, если вы хотите использовать регулярные выражения, вам нужно будет заменить все вхождения символа ASCII 0 (NUL) строкой-заполнителем, а затем сопоставить это при разделении, а затем восстановить символы ASCII 0 (NUL), которые не были разделены впоследствии. Но вам нужно будет убедиться, что ваш заполнитель никогда не появится где-либо еще в вашей строке.

Вместо этого вы можете использовать CHR(0) для соответствия символу NUL. Этот метод использует простые строковые функции (вместо медленных регулярных выражений, которые не могут напрямую обрабатывать ASCII 0 (NUL) символов) и может обрабатывать несколько входных строк:

WITH data ( value ) AS (
  SELECT 'RANDOM' || CHR(0)
         || 'THIS_SHOULD_BE_SPLIT' || CHR(0)
         || '~THIS_IS_NEW' || CHR(0)
         || 'STRING' || CHR(0)
         || '~THIS_IS_ANOTHER_STRING' || CHR(0)
  FROM   DUAL
UNION ALL
  SELECT '12345' || CHR(0)
         || '67890' || CHR(0)
         || '~23456'
  FROM   DUAL
),
split_positions ( value, start_pos, end_pos ) AS (
  SELECT value, 1, INSTR( value, CHR(0) || '~' )
  FROM   data
UNION ALL
  SELECT value, end_pos + 2, INSTR( value, CHR(0) || '~', end_pos + 2 )
  FROM   split_positions
  WHERE  end_pos > 0
)
SELECT CASE end_pos
       WHEN 0
       THEN SUBSTR( value, start_pos )
       ELSE SUBSTR( value, start_pos, end_pos - start_pos )
       END AS value
FROM   split_positions;

Какие выходные данные:

| VALUE                           |
| :------------------------------ |
| RANDOM(NUL)THIS_SHOULD_BE_SPLIT |
| 12345(NUL)67890                 |
| THIS_IS_NEW(NUL)STRING          |
| 23456                           |
| THIS_IS_ANOTHER_STRING(NUL)     |

(Примечание: символ NUL снова был заменен строкой (NUL) в выводе, поскольку скрипту db <> не понравилось отображение этого символа.)

db <> fiddle здесь

0 голосов
/ 28 мая 2020

Что-то вроде этого подойдет вам:

SELECT REGEXP_SUBSTR(replace(stringval, '(NUL)~', '~'),'[^~]+', 1, LEVEL) 
       AS error_code 
FROM test
CONNECT BY REGEXP_SUBSTR(stringval, '[^~]+',1,LEVEL) IS NOT NULL;

вот демо

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