提问者:小点点

替换SQL中标记的宽度属性


我在数据库中包含500页的超文本标记语言的表。所有这些内容包含

我想从所有图像中删除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%:应为数字,但改为saw%”

预期字符串

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

共2个答案

匿名用户

该解决方案是针对Oracle数据库的,因为不清楚该解决方案正在搜索哪个DBMS

如果width始终位于img标记之后,您可以在Oracle数据库中使用Replace功能执行此操作

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

update语句可能类似于

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

如果属性width不直接位于img标记之后,则必须首先找到img标记。这可以通过正则表达式实现。这里不止一次讨论了如何找到img标签。

检查这个问题

用户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测试

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

匿名用户

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

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

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

选择convert(varchar(max),convert(xml,x))作为从@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>