Разделенное сообщение Oracle с regexp_substr

Мне нужно разделить сообщение:

 500 Oracle Parkway.Redwood Shores.*.=13

Теперь у меня есть немного проработанное решение для Substr1/2/4.

  SELECT '500 Oracle Parkway.Redwood Shores.*.=13' string1,
  REGEXP_SUBSTR('500 Oracle Parkway.Redwood Shores.*.=13','.[^.]+') 
  "SUBSTR1" ,
  replace(REGEXP_SUBSTR('500 Oracle Parkway.Redwood Shores.*.=13','[$.]+
  [^.]+'),'.',null) "SUBSTR2" ,
  REGEXP_SUBSTR('500 Oracle Parkway.Redwood Shores.*.=13','[$.]+.[$.]+[^.]') 
  "SUBSTR3" ,
  REGEXP_SUBSTR('500 Oracle Parkway.Redwood Shores.*.=13','[^=]+$') 
  "SUBSTR4" 
  FROM DUAL;

Однако Substr3 содержит '='. Я хотел бы иметь по крайней мере '.*.' или же ' * '

Не могли бы вы дать мне подсказку, как «исключить» любые символы (например, «=») в регулярном выражении?

Любая помощь высоко ценится!

Спасибо

Решено, см. SUBSTR3.1

      SELECT
     '500 Oracle Parkway.Redwood Shores.*.=13' string1,
      REGEXP_SUBSTR('500 Oracle Parkway.Redwood Shores.*.=13','.[^.]+') 
      "SUBSTR1" ,
      replace(REGEXP_SUBSTR('500 Oracle Parkway.Redwood Shores.*.=13','[$.]+
      [^.]+'),'.',null) "SUBSTR2" ,
      REGEXP_SUBSTR('500 Oracle Parkway.Redwood Shores.*.=13','[$.]+.[$.]+
      [^.]') "SUBSTR3" ,
      REGEXP_SUBSTR('500 Oracle Parkway.Redwood Shores.*.=13','[^.]+',1,3) 
      "SUBSTR3.1" ,
      REGEXP_SUBSTR('500 Oracle Parkway.Redwood Shores.*.=13','[^=]+$') 
      "SUBSTR4" 
      FROM DUAL;

person AlexPes    schedule 10.05.2017    source источник
comment
Вы явно включаете = (или любой символ, следующий за .*.) в последнюю часть шаблона, [^.]. Так что простое удаление этого даст вам быстрое решение. Но было бы полезно объяснить больше о том, что вы пытаетесь сделать, и привести больше примеров исходных строк и результатов, которых вы пытаетесь достичь для всех из них. substr2 в вашем примере равно нулю. Вы действительно пытаетесь токенизировать строку, и они (возможно) удаляют = из окончательного токена?   -  person Alex Poole    schedule 10.05.2017


Ответы (2)


С большим уважением к Алексу Пулу, регулярное выражение формата '[^.]+' не работает, если отсутствует один из элементов списка. Он будет молча возвращать неверные данные. Пожалуйста, используйте эту форму вместо этого. Обратите внимание, что я удалил город из первого примера. Попробуйте и вы удивитесь:

with t (str) as (
  select '500 Oracle Parkway..*.=13' from dual union 
  select 'One Microsoft Way.Redmond.Washington.=27' from dual
)
select str,
  regexp_substr(str, '(.*?)(\.|$)', 1, 1, NULL, 1) as substr1,
  regexp_substr(str, '(.*?)(\.|$)', 1, 2, NULL, 1) as substr2,
  regexp_substr(str, '(.*?)(\.|$)', 1, 3, NULL, 1) as substr3,
  ltrim(regexp_substr(str, '(.*?)(\.|$)', 1, 4, NULL, 1), '=') as substr4
from t;

См. здесь для получения дополнительной информации: Разделить значения, разделенные запятыми, на столбцы в оракуле

person Gary_W    schedule 10.05.2017

Похоже, вы пытаетесь токенизировать исходную строку на основе точек, и они (возможно) удаляют начальный знак равенства из четвертого токена. Решение, которое вы использовали для своей «подстроки 3.1», можно использовать для всех из них:

with t (str) as (
  select '500 Oracle Parkway.Redwood Shores.*.=13' from dual
  union all select 'One Microsoft Way.Redmond.Washington.=27' from dual
)
select str,
  regexp_substr(str, '[^.]+', 1, 1) as substr1,
  regexp_substr(str, '[^.]+', 1, 2) as substr2,
  regexp_substr(str, '[^.]+', 1, 3) as substr3,
  ltrim(regexp_substr(str, '[^.]+', 1, 4), '=') as substr4
from t;

STR                                      SUBSTR1              SUBSTR2              SUBSTR3    SUBSTR4
---------------------------------------- -------------------- -------------------- ---------- -------
500 Oracle Parkway.Redwood Shores.*.=13  500 Oracle Parkway   Redwood Shores       *          13     
One Microsoft Way.Redmond.Washington.=27 One Microsoft Way    Redmond              Washington 27     
person Alex Poole    schedule 10.05.2017
comment
@Alex Poole Извини, Алекс. :-) Я выполняю миссию одного человека, чтобы заставить людей прекратить использовать формат регулярного выражения для синтаксического анализа строк '[^.]+' с тех пор, как я обнаружил ошибку, упомянутую в моем посте в производственном отчете. С тех пор я инкапсулировал код в служебную функцию, в которую разработчики могут передавать строку и номер элемента, который они хотят, и функция возвращает элемент, полностью скрывая регулярное выражение для простоты. Я разместил его где-то здесь. Присоединяйтесь ко мне в распространении информации! - person Gary_W; 10.05.2017
comment
@Gary_W - я помню, что об этом упоминалось раньше, но этот шаблон настолько распространен, что я забываю искать более безопасный (или я слишком ленив, если думаю, что это может не иметь значения ... кажется, здесь это имеет значение). Я добавил в закладки ответ, на который вы сейчас ссылаетесь * 8-) - person Alex Poole; 10.05.2017