首页 > 解决方案 > 正则表达式 - 替换样式属性内的编码引号

问题描述

我需要帮助编写正则表达式来解析 HTML 字符串以替换style属性内的编码引号。我的 HTML 字符串中有内容包含不应替换的相同编码引号(不在样式标签内)。这是我失败的正则表达式:

/style=".*(")*.*"/ig

显然,这是错误的,因为我在 RegEx 方面的技能很少。例如,这是我要替换的内容:

<p style="font-family:&quot;Times New Roman&quot; color: red; background:url(&quot;whatever&quot;);">test1</p><p style="font-family:&quot;Times New Roman&quot; color: blue;">THIS IS CONTENT &quot;DO NOT REPLACE!&quot;</p><p style="font-family:&quot;Times New Roman&quot; color: green;">test</p><p style="font-family:&quot;Times New Roman&quot; color: orange;">test2</p>

我想要的输出:

<p style="font-family:'Times New Roman' color: red; background:url('whatever');">test1</p><p style="font-family:'Times New Roman'; color: blue;">THIS IS CONTENT &quot;DO NOT REPLACE!&quot;</p><p style="font-family:'Times New Roman' color: green;">test</p><p style="font-family:'Times New Roman' color: orange;">test2</p>

&quot;应替换 中的所有实例style="…",但不能替换 HTML 标记内容区域中的实例。非常感谢这里的任何帮助!

标签: regex

解决方案


您的 regexp 有几个问题/style=".*(&quot;)*.*"/ig

  • 字符点 (.) 将匹配任何内容,因此 (.)* 将一直匹配到字符串的末尾,直到它看到双引号 "

  • 您使用(&quot;)** 指定,因此它将匹配任何样式 =“...”,即使 (&quot;)样式中没有。

为了克服这个问题,我认为您需要指定在 内接受哪些字符style(&quot;)并且它可以在样式内发生任意次数。

像这样的正则表达式将起作用:

regexp = /style="(([a-z0-9:-]|;|\s|\(|\))*(&quot;)([a-z0-9:-]|;|\s|\(|\))*)*"/i

Toto 在评论中建议了一个更好的版本:

regexp = /style="([a-z0-9:;\s()-]*(&quot;)[a-z0-9:;\s()-]*)*"/i

这是我用 Ruby 编写的一个程序来测试它:

st = %q(
  <p style="font-family:&quot;Times New Roman&quot; color: red; background:url(&quot;whatever&quot;);">test1</p>
  <p style="font-family:&quot;Times New Roman&quot; color: blue;">THIS IS CONTENT &quot;DO NOT REPLACE!&quot;</p>
  <p style="font-family:&quot;Times New Roman&quot; color: green;">test</p>
  <p style="font-family:&quot;Times New Roman&quot; color: orange;">test2</p>
  )

def replace_quotes_in_styles(st)
  regexp = /style="(([a-z0-9:-]|;|\s|\(|\))*(&quot;)([a-z0-9:-]|;|\s|\(|\))*)*"/i

  while (match_data = st.match(regexp)) do
    st = st.sub(match_data.to_s, match_data.to_s.gsub("&quot;", "'") )
  end

  st
end

puts replace_quotes_in_styles(st)

它将打印一些这样的输出:

<p style="font-family:'Times New Roman' color: red; background:url('whatever');">test1</p>
<p style="font-family:'Times New Roman' color: blue;">THIS IS CONTENT &quot;DO NOT REPLACE!&quot;</p>
<p style="font-family:'Times New Roman' color: green;">test</p>
<p style="font-family:'Times New Roman' color: orange;">test2</p>

或更简洁的程序:

 st = %q(
  <p style="font-family:&quot;Times New Roman&quot; color: red; background:url(&quot;whatever&quot;);">test1</p>
  <p style="font-family:&quot;Times New Roman&quot; color: blue;">THIS IS CONTENT &quot;DO NOT REPLACE!&quot;</p>
  <p style="font-family:&quot;Times New Roman&quot; color: green;">test</p>
  <p style="font-family:&quot;Times New Roman&quot; color: orange;">test2</p>
  )

def replace_quotes_in_styles(st)
  regexp = /style="([a-z0-9:;\s()-]*(&quot;)[a-z0-9:;\s()-]*)*"/i
  st.gsub(regexp) { |s| s.gsub("&quot;", "'") }
end

puts replace_quotes_in_styles(st)

推荐阅读