sql >> データベース >  >> RDS >> Mysql

mysqlはhtmlの特殊文字をUTFに相当するものに置き換えます

    上記のコメント 、あなたが自分のケースで何をしようとしているのかはひどく不明確です。

    はい、そうです。文字コードエンティティを置き換えることができます(例:{ およびƫ )「マッピング」で文字コードを検索することなく、置換文字を使用します。ただし、名前付きエンティティ(例:" )常に検索する必要があります。

    一般的なケースを解決するための私の試みは次のとおりです。

    1. HTMLで定義された名前付き文字エンティティを格納するテーブルを作成します:

      CREATE TABLE ents (
        ref VARCHAR(8) NOT NULL COLLATE utf8_bin,
        rep CHAR(1)    NOT NULL,
        PRIMARY KEY (ref)
      );
      
    2. このテーブルにデータを入力します-たとえば、PHPのスクリプトを使用することをお勧めします:

      $dbh = new PDO("mysql:dbname=$dbname", $username, $password);
      $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
      $ins = $dbh->prepare('INSERT INTO ents (ref, rep) VALUES (?, ?)');
      $t = get_html_translation_table(HTML_ENTITIES);
      foreach ($t as $k => $v) $ins->execute([substr($v, 1, -1), $k]);
      
    3. エンティティの置換を実行するSQL関数を定義します(該当する場合はこのテーブルを使用するか、文字コードで):

      DELIMITER ;;
      
      CREATE FUNCTION dhe(s TEXT) RETURNS TEXT
      BEGIN
        DECLARE n, p, i, t INT DEFAULT 0;
        DECLARE r VARCHAR(12);
        entity_search: LOOP
          SET n := LOCATE('&', s, n+1);
          IF (!n) THEN
            LEAVE entity_search;
          END IF;
      
          IF (SUBSTRING(s, n+1, 1) = '#') THEN
            CASE
              WHEN SUBSTRING(s, n+2, 1) RLIKE '[[:digit:]]' THEN
                SET t := 2, p := n+2, r := '[[:digit:]]';
              WHEN SUBSTRING(s, n+2, 1) = 'x' THEN
                SET t := 3, p := n+3, r := '[[:xdigit:]]';
              ELSE ITERATE entity_search;
            END CASE;
          ELSE
            SET t := 1, p := n+1, r := '[[:alnum:]_]';
          END IF;
      
          SET i := 0;
          reference: LOOP
            IF SUBSTRING(s, p+i, 1) NOT RLIKE r THEN
              IF SUBSTRING(s, p+i, 1) RLIKE '[[:alnum:]_]' THEN
                ITERATE entity_search;
              END IF;
              LEAVE reference;
            END IF;
            IF i = 8 THEN ITERATE entity_search; END IF;
            SET i := i + 1;
          END LOOP reference;
      
          SET s := CONCAT(
            LEFT(s, n-1),
            CASE t
              WHEN 1 THEN COALESCE(
                (SELECT rep FROM ents WHERE ref = SUBSTRING(s, p, i))
              , SUBSTRING(s, n, i + IF(SUBSTRING(s, p+i, 1)=';',1,0))
              )
              WHEN 2 THEN CHAR(SUBSTRING(s, p, i))
              WHEN 3 THEN CHAR(CONV(SUBSTRING(s, p, i), 16, 10))
            END,
            SUBSTRING(s, p + i + IF(SUBSTRING(s, p+i, 1)=';',1,0))
          );
        END LOOP entity_search;
        RETURN s;
      END;;
      
      DELIMITER ;
      
    4. この関数を2回適用します (明らかに)二重にエンコードされたテーブルをデコードするには:

      UPDATE my_table SET my_column = dhe(dhe(my_column));
      


    1. mysqlでvarbinaryからchar/varcharに変換する方法

    2. HubSpotODBCドライバー

    3. トランザクション内でのGOの使用

    4. MySqlクエリのヘルプ-特定の列のグループごとの最大値を保持する行