要更改文本周围的标记对,此Postgres SELECT表达式适用于我:
select regexp_replace('The corpse of the huge <i>fin whale</i> created a spectacle on <span class="day">Friday</span> as <i>people</i> wandered the beach to observe it.',
'(<i>)([^/]+)(</i>)',
'<em>\2</em>',
'g');
我担心参考二号过度贪婪。我第一次尝试参考第二个是(。+),这是一个失败。 ([^ /] +)效果更好。但我不知道它是否足够好。
可以做些什么来使SELECT语句更健壮吗?
答案 0 :(得分:5)
通常有两种可能性(and both seem to be supported by PostreSQL's regex engine)。
不重复的重复:
<i>(.+?)</i>
使用negative lookahead确保您使用</i>
以外的任何内容:
<i>((?:(?!</i>).)+)</i>
在这两种情况下,我删除了不必要的捕获。您现在可以在替换字符串中使用\1
。
这两个应该与他们所做的相同。他们的表现可能会有所不同前者需要回溯,而后者必须在每一个位置尝试前瞻。哪一个更快,必须进行分析,甚至可能依赖于单个输入字符串。请注意,由于第二个模式使用贪婪重复,您可以删除尾随</i>
,您仍然会得到相同的结果。
您所拥有的方法已经非常强大,因为您永远无法超越</i>
。但与此同时,您的方法不允许嵌套标记(因为重复不能超过嵌套对的结束标记)。
但是,您应该注意regular expressions are not really up to the job of parsing/manipulating HTML。如果您的代码中有多余的空格怎么办?或者如果开始标记有属性怎么办?或者如果一个或两个标签出现在属性名称或注释中会怎么样?