【问题标题】:Replace string with wildcard用通配符替换字符串
【发布时间】:2017-04-12 16:51:36
【问题描述】:

我正在将我管理的网站从自定义 CMS 转移到 Wordpress,并且发现图像标签上的某些属性一旦在 WP 环境中显示就会出现问题。为了解决这个问题,我需要去掉wp_posts 表的post_content 列中每个图像标签内联的高度属性。

从数据库中的原始值开始,我想要以下内容:

<img src="http://example.com/img/20150823_image.jpg" style="width: 730px; height: 730px;" />

成为:

<img src="http://example.com/img/20150823_image.jpg" style="width: 730px;" />

所以,基本上,我需要修剪“高度:730px;”部分。它是特定于图像的,因此在这种情况下是 730,但在另一种情况下可能是 1500、447、80 等。

我试图查看是否可以使用“%”作为通配符,但这似乎不起作用...

UPDATE wp_posts SET post_content = REPLACE(post_content,' height: %px;','');

任何帮助都将不胜感激,因为我宁愿不必手动检查数千行来删除它们。

【问题讨论】:

  • 您需要使用正则表达式进行替换。不幸的是,SQL 没有在替换函数中提供该功能。最好的办法是编写一个 php 脚本来逐行遍历并进行替换。
  • 这里有一些关于 LIKE 的文档,也许会有所帮助。 docs.microsoft.com/en-us/sql/t-sql/language-elements/…

标签: mysql database wordpress replace


【解决方案1】:

您可以使用函数来进行文本解析:

create function f_strip_height( in_s text ) returns text
begin

declare v_start int;
declare v_end int;
declare v_height text;

select locate(' height:', in_s ) into v_start;
if (v_start>0) then

  select locate( 'px;', substring( in_s, v_start)  ) into v_end;

  select trim(substring(substring( in_s, v_start, v_end+2), 9)) into v_height;

  if (v_end>0 and concat(cast(v_height as unsigned), 'px;' =  v_height)) then
    return concat(substring( in_s, 1, v_start-1), substring( in_s, v_start+v_end+2));
  end if;
end if;

return in_s;
end

然后使用函数:

UPDATE wp_posts SET post_content = f_strip_height(post_content);

【讨论】:

  • 这将起作用,只要格式完全相同(style 是元素的最后一个属性,height 是该属性内的最后一个规则,始终使用双引号,元素是自动关闭的,等等)
  • 可以很容易地改进功能使其更通用。修改了示例代码。
  • 那不是我的意思,因为我可以继续玩这个游戏:height: 0; 呢,如果它是最后一条规则并且没有分号,那么其他设置了高度的元素呢?我想说的是,仅使用子字符串索引解析标记将非常脆弱,甚至比 parsing markup with regular expressions!
  • (作为记录,我很清楚这是在吹毛求疵;我仍然为你的努力投了赞成票!)
  • 用例非常简单,目的不是创建一个完整的 CSS 解析器。只需查看数据中存在的 CSS 高度组合并为此准备函数即可。更新运行后,SSeybold 可以将数据传输到 Wordpress。
【解决方案2】:

这不是 SQL 的工作。这是一个简单的 (?) PHP 脚本,应该可以解决问题,尽管我是在想办法做到这一点,所以不能保证:

<?php
// create the DB connection
$db = new PDO("mysql:host=localhost;dbname=wordpress", "user", "password");
// quiet warnings
libxml_use_internal_errors(true);
// prepare the update statement for later
$stmt = $db->prepare("UPDATE wp_posts SET post_content = ? WHERE post_id = ?");
// select the posts that at least have the word "height:" in them
$posts = $db->query("SELECT post_id, post_content FROM wp_posts WHERE post_content LIKE '%height:%'");
// loop through the posts
while ($post = $posts->fetch(PDO::FETCH_ASSOC)) {
    // create a DOM document
    $dom = new DomDocument();
    // load the HTML into the DOM parser
    $dom->loadHTML($post["post_content"], LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
    // prepare the XPath
    $xpath = new DomXPath($dom);
    // get all img elements with a style attribute containing the word height
    $imgs = $xpath->query("//img[contains(@style, 'height')]");
    foreach ($imgs as $img) {
        // get the style attribute value
        $style = $img->getAttribute("style");
        // remove height
        $style = preg_replace("/height\s*:\s*\d+(px)?;?/", "", $style);
        // replace the attribute value
        $img->setAttribute("style", $style);
    }
    // output the new HTML
    $newhtml = $dom->saveHTML();
    echo "Updating post $post["post_id"] with new content:\n$newhtml\n\n";
    // save it into the database -- uncomment this line when you trust the script!
//    $stmt->execute([$newhtml, $post["post_id"]]);
}

【讨论】:

    【解决方案3】:

    如果你有相应的权限,你可以使用 UDF 27.4.2 Adding a New User-Defined Function,一些可以是:

    在另一种情况下,如前所述,您可以执行自己的功能,这里是您可以根据需要修改和调整的版本:

    mysql> DROP TABLE IF EXISTS `wp_posts`;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> CREATE TABLE IF NOT EXISTS `wp_posts` (
        ->     `post_content` TEXT
        -> );
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> INSERT INTO `wp_posts`
        ->     (`post_content`)
        -> VALUES
        ->     ('<img src="http://example.com/img/20150823_image.jpg" style="width: 730px; height: 730px;" />'),
        ->     ('<img src="http://example.com/img/20150824_image.jpg" style="width: 730px; height: 1500px;" />'),
        ->     ('<img src="http://example.com/img/20150825_image.jpg" style="width: 730px; height: 80px;" />'),
        ->     ('<img src="http://example.com/img/20150826_image.jpg" style="width: 730px; height: 0px;" />'),
        ->     ('<img src="http://example.com/img/20150827_image.jpg" style="width: 730px;" />');
    Query OK, 5 rows affected (0.01 sec)
    Records: 5  Duplicates: 0  Warnings: 0
    
    mysql> DELIMITER //
    
    mysql> DROP FUNCTION IF EXISTS `get_string`//
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> CREATE FUNCTION `get_string`(`_string` TEXT,
        ->                              `_begin` VARCHAR(255),
        ->                              `_end` VARCHAR(255))
        ->     RETURNS TEXT DETERMINISTIC
        -> BEGIN
        ->     DECLARE `_begin_pos` INT UNSIGNED DEFAULT LOCATE(`_begin`, `_string`);
        ->     DECLARE `_end_pos` INT UNSIGNED DEFAULT 0;
        ->     IF `_begin_pos` IS NOT NULL AND `_begin_pos` > 0 THEN
        ->         SET `_end_pos` := LOCATE(`_end`, `_string`, `_begin_pos`);
        ->         IF `_end_pos` IS NOT NULL AND `_end_pos` > 0 THEN
        ->             RETURN SUBSTRING(`_string`,
        ->                              `_begin_pos`,
        ->                              (`_end_pos` + CHAR_LENGTH(`_end`)) - `_begin_pos`); 
        ->         END IF;
        ->     END IF;
        ->     RETURN '';
        -> END//
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> DELIMITER ;
    
    mysql> SELECT `post_content`
        -> FROM `wp_posts`;
    +-----------------------------------------------------------------------------------------------+
    | post_content                                                                                  |
    +-----------------------------------------------------------------------------------------------+
    | <img src="http://example.com/img/20150823_image.jpg" style="width: 730px; height: 730px;" />  |
    | <img src="http://example.com/img/20150824_image.jpg" style="width: 730px; height: 1500px;" /> |
    | <img src="http://example.com/img/20150825_image.jpg" style="width: 730px; height: 80px;" />   |
    | <img src="http://example.com/img/20150826_image.jpg" style="width: 730px; height: 0px;" />    |
    | <img src="http://example.com/img/20150827_image.jpg" style="width: 730px;" />                 |
    +-----------------------------------------------------------------------------------------------+
    5 rows in set (0.00 sec)
    
    mysql> UPDATE `wp_posts`
        -> SET `post_content` = REPLACE(`post_content`, `get_string`(`post_content`, ' height:', ';'), '');
    Query OK, 4 rows affected (0.01 sec)
    Rows matched: 5  Changed: 4  Warnings: 0
    
    mysql> SELECT `post_content`
        -> FROM `wp_posts`;
    +-------------------------------------------------------------------------------+
    | post_content                                                                  |
    +-------------------------------------------------------------------------------+
    | <img src="http://example.com/img/20150823_image.jpg" style="width: 730px;" /> |
    | <img src="http://example.com/img/20150824_image.jpg" style="width: 730px;" /> |
    | <img src="http://example.com/img/20150825_image.jpg" style="width: 730px;" /> |
    | <img src="http://example.com/img/20150826_image.jpg" style="width: 730px;" /> |
    | <img src="http://example.com/img/20150827_image.jpg" style="width: 730px;" /> |
    +-------------------------------------------------------------------------------+
    5 rows in set (0.00 sec)
    

    Rextester 中的示例。

    【讨论】:

    • 如果它是可以复制/粘贴的形式,这可能会更有帮助。
    • @miken32:添加示例。
    猜你喜欢
    • 1970-01-01
    • 2012-11-21
    • 2012-02-01
    • 1970-01-01
    • 2016-10-08
    • 2017-05-27
    • 2014-02-11
    • 2021-03-24
    • 1970-01-01
    相关资源
    最近更新 更多