Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL REPLACE :Wie alle Vorkommen eines Zeichens in jeder einzelnen Teilzeichenfolge ersetzt werden, die durch denselben Kopf und dasselbe Ende begrenzt sind

Es ist nur in reinem MySQL möglich, ohne dass ein vollständiger HTML-Parser oder eine UDF verwendet wird, die die REGEX_REPLACE-Funktion in MySQL importieren würde.

Der Trick besteht darin, einen Zahlengenerator zu verwenden und einen verschachtelten SUBSTRING_INDEX zu verwenden, um die große Zeichenfolge auf die HTML-Tags aufzuteilen.
Dieser Zahlengenerator generiert Zahlen von 1 bis 10.000.
Der "Parser" unterstützt also bis zu 10.000 Tags, wenn Sie mehr brauchen, müssen Sie weitere hinzufügen

CROSS JOIN (
     SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
    ) AS record_[number]

Abfrage

SELECT 
 (@number := @number + 1) AS number
FROM (    
  SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
) AS record_1
CROSS JOIN (
  SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
) AS record_2
CROSS JOIN (
 SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
) AS record_3
CROSS JOIN (
  SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
) AS record_4
CROSS JOIN ( SELECT @number := 0 ) AS init_user_param

Diese SQL-Anweisung wird verwendet, um das HTML-Tag

aufzuteilen

SQL-Anweisung

CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX([large_html_string], ">", [tag_position]), ">", -1), ">") as tag 

Der Trick besteht nun darin, den Zahlengenerator und den HTML-String splittig zu kombinieren. Die [tag_position] wird also mit einer Zahl aus dem Zahlengenerator gefüllt.
Dies geschieht mit einem CROSS JOIN.

Abfrage

SELECT 
 *
FROM ( 

  SELECT 
    CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(data, ">", generator.number), ">", -1), ">") as tag 
  FROM (

    SELECT '<p><span><b>C10373 - FIAT GROUP AUTOMOBILES/RAMO DI AZIENDA DI KUEHNE + NAGEL</b></span>
    <p>la somma pari a € 400+IVA per l’attività</p>
    <p>TELE+ A 20.000 LIRE AL MESE </p>
    <li>a mano o via fax al numero +39.00.0.0.0.00.</li>
    <p>Il punteggio base sarà incrementato di un <strong>+ </strong>al ricorrere di ciascuna delle seguenti condizioni:</p>
    <li><a href="/aaa/gare/CIGZB81E5568D+RDO1560277+Obblighi+contattuali-signed.pdf" title="">Obblighi contrattuali</a></li> 
    <li><a href="/aaa/gare/CIGZB81E5568D+RDO1560277+Obblighi+contattuali-signed.pdf" title="">Obblighi contrattuali</a></li> 
    <li><a href="/aaa/gare/CIGZB81E5568D+RDO_1560277Lettera_Invito.pdf" title="">Lettera di invito</a></li>
    <li><a href="/aaa/gare/CIGZB81E5568D+RDO1560277+Obblighi+contattuali-signed.pdf" title="">Obblighi contrattuali</a></li> 
    <li><a href="/aaa/gare/CIGZB81E5568D+RDO1560277+disciplinare+di+gara-signed.pdf" title="">Disciplinare di gara</a></li>
    <li><a href="/aaa/gare/CIGZB81E5568D+determina+di+aggiudicazione+58+2017.pdf" title="">Determina di aggiudicazione</a></li>' AS data

   ) AS record 
   CROSS JOIN (
     SELECT 
       (@number := @number + 1) AS number
     FROM (    
       SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
     ) AS record_1
     CROSS JOIN (
       SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
     ) AS record_2
     CROSS JOIN (
       SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
     ) AS record_3
     CROSS JOIN (
       SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
     ) AS record_4
     CROSS JOIN ( SELECT @number := 0 ) AS init_user_param
   ) 
    AS generator
 ) 
 AS tags
WHERE 
 tags.tag != '>'

siehe Demo http://www.sqlfiddle.com/#!9/de2ed/32

Jetzt haben wir die Tags als getrennte Datensätze, es ist wirklich einfach, sie nur durch Datensätze zu ersetzen, die "href" enthalten.

SQL-Anweisung

 (
    CASE 
      WHEN 
        LOCATE("href", tags.tag) > 0
      THEN 
        REPLACE(tags.tag, "+", " ") 
      ELSE 
        tags.tag
    END
 ) AS tag

siehe Demo http://www.sqlfiddle.com/#!9/de2ed/38

Jetzt, da wir wissen, wie man ersetzt, werden wir die Datensätze wieder zu einer Zeichenfolge zusammenführen. Dafür können wir GROUP_CONCAT verwenden.

Abfrage

    SET SESSION group_concat_max_len = @@max_allowed_packet;

    SELECT 
     GROUP_CONCAT(
        CASE 
          WHEN 
            LOCATE("href", tags.tag) > 0
          THEN 
            REPLACE(tags.tag, "+", " ") 
          ELSE 
            tags.tag
        END
       SEPARATOR ""
     ) AS html

    FROM ( 

      SELECT 
        CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(data, ">", generator.number), ">", -1), ">") as tag 
      FROM (

        SELECT '<p><span><b>C10373 - FIAT GROUP AUTOMOBILES/RAMO DI AZIENDA DI KUEHNE + NAGEL</b></span>
        <p>la somma pari a € 400+IVA per l’attività</p>
        <p>TELE+ A 20.000 LIRE AL MESE </p>
        <li>a mano o via fax al numero +39.00.0.0.0.00.</li>
        <p>Il punteggio base sarà incrementato di un <strong>+ </strong>al ricorrere di ciascuna delle seguenti condizioni:</p>
        <li><a href="/aaa/gare/CIGZB81E5568D+RDO1560277+Obblighi+contattuali-signed.pdf" title="">Obblighi contrattuali</a></li> 
        <li><a href="/aaa/gare/CIGZB81E5568D+RDO1560277+Obblighi+contattuali-signed.pdf" title="">Obblighi contrattuali</a></li> 
        <li><a href="/aaa/gare/CIGZB81E5568D+RDO_1560277Lettera_Invito.pdf" title="">Lettera di invito</a></li>
        <li><a href="/aaa/gare/CIGZB81E5568D+RDO1560277+Obblighi+contattuali-signed.pdf" title="">Obblighi contrattuali</a></li> 
        <li><a href="/aaa/gare/CIGZB81E5568D+RDO1560277+disciplinare+di+gara-signed.pdf" title="">Disciplinare di gara</a></li>
        <li><a href="/aaa/gare/CIGZB81E5568D+determina+di+aggiudicazione+58+2017.pdf" title="">Determina di aggiudicazione</a></li>' AS data

       ) AS record 
       CROSS JOIN (
         SELECT 
           (@number := @number + 1) AS number
         FROM (    
           SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
         ) AS record_1
         CROSS JOIN (
           SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
         ) AS record_2
         CROSS JOIN (
           SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
         ) AS record_3
         CROSS JOIN (
           SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10
         ) AS record_4
         CROSS JOIN ( SELECT @number := 0 ) AS init_user_param
       ) 
        AS generator
     ) 
     AS tags
    WHERE 
     tags.tag != '>'

siehe Demo für die vollständige Abfrage

http://www.sqlfiddle.com/#!9/de2ed/46