【问题标题】:Replace <img> tag's width attribute in SQL替换 SQL 中的 <img> 标签宽度属性
【发布时间】:2019-02-05 04:35:34
【问题描述】:

我在数据库中有一个包含 500 页 HTML 的表。所有这些内容都包含&lt;img width="100%".....

我想从所有图像中删除 width="100%" 而不影响其余内容。

例如 当前字符串

<img width="100%" src="/images/skyline.jpg" alt="Image showing sky line" />

<img src="/images/skyline.jpg" width="100%" alt="Image showing sky line" />

W3C 验证将此检测为错误 - “元素 img 上属性宽度的错误值为 100%:应为数字但看到的是 %。”

预期的字符串

<img src="/images/skyline.jpg" alt="Image showing sky line" />

【问题讨论】:

    标签: html sql-server image replace


    【解决方案1】:

    该解决方案适用于 Oracle DB,因为尚不清楚该解决方案正在搜索哪个 DBMS

    如果width 总是在img 标记之后,您可以在Oracle 数据库中使用Replace 函数来做到这一点,例如

    replace (<column>,'<img width="100%" ','<img ');
    

    更新语句可能是这样的

    update <table>
    set <column> = replace (<column>,'<img width="100%" ','<img ')
    

    如果属性width 没有直接出现在img 标记之后,那么您必须先找到IMG 标记。这可以用正则表达式来完成。 如何找到 img 标签在这里已经讨论过不止一次了。

    check this question

    这个修改后的用户 sln 正则表达式可能对你有用:

     <img\s[^>]*?(width\s*=\s*[''\"]([^''\"]*?)[''\"])([^>]*?)>
    

    首先要找到img标签,过滤掉信息

    replace(REGEXP_SUBSTR(txt,'<img\s[^>]*?width\s*=\s*[''\"]([^''\"]*?)[''\"][^>]*?>'),'width="100%" ','') 
    

    然后你可以用整个html中的过滤标签替换img标签,看起来像这样:

    REGEXP_REPLACE(txt
                 , '<img\s[^>]*?(width\s*=\s*[''\"]([^''\"]*?)[''\"])([^>]*?)>'
                 , replace(REGEXP_SUBSTR(txt,'<img\s[^>]*?width\s*=\s*[''\"]([^''\"]*?)[''\"][^>]*?>'),'width="100%" ','')          
                 )
    

    SQLFiddel Test

    这可能不是最佳选择,但可能会有所帮助

    【讨论】:

    • 根据我上面提出的问题,这不起作用,因为在宽度属性之前的 img 标签内可以有其他任何东西。
    • @TomC 如果您在问题中没有更详细的信息,那么您将无法给出更准确的答案。我现在改了答案
    • 没问题。我也有 sqlserver 的替代方案,但由于它目前处于搁置状态,无法添加它。我们在 sql server 中没有 regex_replace ,这很遗憾,因为一旦您正确使用了正则表达式,它就变得相对简单!很高兴看到你也理解了这个问题。不知道为什么它被搁置了。
    【解决方案2】:

    这将适用于 sql server。我已经包含了一些示例 img 标签来展示它是如何工作的。

    但请注意,它会重新格式化 html,这可能并不理想。它将是相同的 html,但没有额外的空格和换行符。这可能不是你想要的。

    我必须这样做的原因是当我转换为 xml 然后找到节点时,结果会被修剪掉额外的空白,并且无法在原始字符串中找到它们。如果您的 html 在 img 标签内没有多余的空格,那么您可以省略这一步:

    select convert(varchar(max),convert(xml,x)) as trimmed from @t

    如果这对您不起作用,那么希望匹配节点的识别至少会有所帮助。只需在匹配的 cte 后添加 select * from matching 即可查看您有什么。

    它还可以在逐个文档的基础上工作,因此您可能必须将其置于循环中才能处理您的文档。或者更新它以跨批次工作,但我猜这是一次性操作,因此可能不需要。

    declare @t table(x varchar(max))
    insert @t values ('<html><div><img width="50%" /><img    width="100%" src="foo" alt="bar" />
    <span class="c">sometext</span>
    <div><img src="foo" alt="bah" width="100%"  /></div></div>
    </html>')
    
    ;with [xml] as (
        --- convert the string to xml
        select convert(xml,x) as x from @t
    )
    ,matching as (
        -- Find all the img nodes that have width=100%
        select convert(varchar(max),c.query('.')) as matches
        from [xml]
        cross apply x.nodes('//img[@width="100%"]') as t(c)
    ) 
    ,source as (
        -- Tidy up the source, as it has multiple spaces that prevent the matches from finding the nodes
        select convert(varchar(max),convert(xml,x)) as trimmed from @t
    )
    ,replaced as (
        -- Work through recursively removing the 100% from matching nodes
        select trimmed from source
        union all
        select replace(trimmed,matches,replace(matches,'width="100%"','')) as replaced from matching
        cross join replaced
        where charindex(matches,replaced.trimmed)>0
    )
    -- Get the shortest (or last) string from above
    select top 1 * from replaced order by len(trimmed) 
    

    输出:

    <html><div><img width="50%"/><img  src="foo" alt="bar"/><span class="c">sometext</span><div><img src="foo" alt="bah" /></div></div></html>
    

    【讨论】:

      猜你喜欢
      • 2014-03-12
      • 1970-01-01
      • 2021-07-11
      • 2023-03-09
      • 2013-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多