Oracle - Regex заменяет ([0-9] {1,} \. [0-9] {1,}) на 0,00, но не окружает <qCom></qCom> - PullRequest
0 голосов
/ 31 октября 2018

Я должен заменить значения внутри тегов XML, чтобы сделать значение нулевым

Пример:

<cProd>7898132541927</cProd>
<cEAN>7898132541927</cEAN>
<uCom>UN</uCom>
<qCom>12.0000</qCom>
<vUnCom>47.6600000000</vUnCom>
<vProd>571.92</vProd>
<cEANTrib>7898132541927</cEANTrib>
<uTrib>UN</uTrib>
<qTrib>12.0000</qTrib>
<vUnTrib>47.6600000000</vUnTrib>
<indTot>1</indTot>

Результат, который мне нужен:

<cProd>7898132541927</cProd>
<cEAN>7898132541927</cEAN>
<uCom>UN</uCom>
<qCom>12.0000</qCom>
<vUnCom>0.00</vUnCom>
<vProd>0.00</vProd>
<cEANTrib>7898132541927</cEANTrib>
<uTrib>UN</uTrib>
<qTrib>12.0000</qTrib>
<vUnTrib>0.00</vUnTrib>
<indTot>1</indTot>

Я должен использовать Oracle, чем написать правильный скрипт:

SELECT
REGEXP_REPLACE('
    <cProd>7898132541927</cProd>
    <cEAN>7898132541927</cEAN>
    <uCom>UN</uCom>
    <qCom>12.0000</qCom>
    <vUnCom>47.6600000000</vUnCom>
    <vProd>571.92</vProd>
    <cEANTrib>7898132541927</cEANTrib>
    <uTrib>UN</uTrib>
    <qTrib>12.0000</qTrib>
    <vUnTrib>47.6600000000</vUnTrib>
    <indTot>1</indTot>
'
, '([0-9]{1,}\.[0-9]{1,})(?!</qCom|?!</qTrib)'
, '0.00') RES
FROM DUAL
;

Регулярное выражение ([0-9]{1,}\.[0-9]{1,}) работает, но в теге qCom и qTrib я должен сделать исключение в регулярном выражении

Кто-то может помочь. Tks

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

Я не мог заставить это работать с отрицательным взглядом сзади ((?<!)), но я заметил, что единственными числами, которые вы хотите установить в 0,00, являются те, которые находятся внутри тегов, начинающихся с v.

Используя положительный взгляд назад ((?<=), этот шаблон регулярного выражения работает:

'(?<=<v[A-Za-z]+>)([0-9]+\.[0-9]+)'

Используется на примере, который вы дали, это даст

<cProd>7898132541927</cProd>
<cEAN>7898132541927</cEAN>
<uCom>UN</uCom>
<qCom>12.0000</qCom>
<vUnCom>0.00</vUnCom>
<vProd>0.00</vProd>
<cEANTrib>7898132541927</cEANTrib>
<uTrib>UN</uTrib>
<qTrib>12.0000</qTrib>
<vUnTrib>0.00</vUnTrib>
<indTot>1</indTot>

Детали регулярного выражения:

'(?<='           Assert that the regex below can be matched, with the match ending at this position (positive lookbehind)
   '<v'          Match the characters “<v” literally
   '[A-Za-z]'    Match a single character present in the list below
                 A character in the range between “A” and “Z”
                 A character in the range between “a” and “z”
      '+'        Between one and unlimited times, as many times as possible, giving back as needed (greedy)
   '>'           Match the character “>” literally
')' 
'('              Match the regular expression below and capture its match into backreference number 1
   '[0-9]'       Match a single character in the range between “0” and “9”
      '+'        Between one and unlimited times, as many times as possible, giving back as needed (greedy)
   '\.'          Match the character “.” literally
   '[0-9]'       Match a single character in the range between “0” and “9”
      '+'        Between one and unlimited times, as many times as possible, giving back as needed (greedy)
')' 
0 голосов
/ 31 октября 2018

Учитывая, что Oracle уже имеет встроенную функцию XML для этого - почему бы не использовать это?

например. с обновлением XQuery (предполагается, что документ XML действителен)

WITH table_name (xmlvalue)
     AS (SELECT XMLTYPE (
'<Document>
  <cProd>7898132541927</cProd>
  <cEAN>7898132541927</cEAN>
  <uCom>UN</uCom>
  <qCom>12.0000</qCom>
  <vUnCom>47.6600000000</vUnCom>
  <vProd>571.92</vProd>
  <cEANTrib>7898132541927</cEANTrib>
  <uTrib>UN</uTrib>
  <qTrib>12.0000</qTrib>
  <vUnTrib>47.6600000000</vUnTrib>
  <indTot>1</indTot>
</Document>') FROM DUAL)
SELECT XMLQUERY (
         'copy $new := $old 
          modify (
             for $node in $new/Document/node()[matches(.,"[0-9]+\.[0-9]+") and not(local-name()=("qCom","qTrib"))] 
             return replace value of node $node with "0.00") 
          return $new'
          PASSING 
             xmlvalue AS "old"
          RETURNING CONTENT) result
FROM   table_name;

<Document>
  <cProd>7898132541927</cProd>
  <cEAN>7898132541927</cEAN>
  <uCom>UN</uCom>
  <qCom>12.0000</qCom>
  <vUnCom>0.00</vUnCom>
  <vProd>0.00</vProd>
  <cEANTrib>7898132541927</cEANTrib>
  <uTrib>UN</uTrib>
  <qTrib>12.0000</qTrib>
  <vUnTrib>0.00</vUnTrib>
  <indTot>1</indTot>
</Document>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...