我在数据库中包含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" />
该解决方案是针对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>