1

我知道这已经被问过一百万次了,所以很抱歉重复了一个问题,但这让我发疯了。我已经为此工作了很长时间,但似乎没有取得任何进展。

我有一些 html 代码,其中包含向右或向左浮动的图像。我需要做的是找到所有浮动的图像,删除浮动,然后将它们包装在一个现在浮动的 div 中,就像图像一样。

例如从

<img src="images/imagepath1.jpg" border="0" alt="image 1" width="200" height="206" style="float: right;" />

<div class="imgContainer" style="float: right;"><img src="images/imagepath1.jpg" border="0" alt="image 1" width="200" height="206" /></div>

我在记事本++查找中使用此代码

<img src="(.+)" border="([0-9]{1})" alt="(.*?)" width="([0-9]{2,3})" height="([0-9]{3})" style="float: (right|left);" />

用。。。来代替

<div class="imgContainer" style="float: \6;"><img src="\1" border="\2" alt="\3" width="\4" height="\5" /></div>

问题是在包含<p>标签和多个图像的代码块中,我从头到尾突出显示整个代码块。

例如

<img src="images/imagepath1.gif" border="0" alt="image 1" width="207" height="119" style="float: right;" /><p>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum</p><p>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum </p><p>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum</p> <img src="images/imagepath2.jpg" border="0" alt="image2" width="96" height="141" style="float: left;" /><p>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum </p><p>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum </p><img src="images/imagepath3.gif" border="0" alt="image 3" width="72" height="108" style="float: right;" />

在记事本++中,这匹配整个块。你能提供任何让我发疯的建议吗!

亚当

4

2 回答 2

1

我会说你走在正确的道路上,距离你想出的正则表达式查找/替换只有一个字符。

这是您当前的发现:

<img src="(.+)" border="([0-9]{1})" alt="(.*?)" width="([0-9]{2,3})" height="([0-9]{3})" style="float: (right|left);" />

将其更改为:

             v

<img src="(.+?)" border="([0-9]{1})" alt="(.*?)" width="([0-9]{2,3})" height="([0-9]{3})" style="float: (right|left);" />

v显示了我在哪里介绍了您当前缺少的 1 个字符。一旦你让它变得.+懒惰,你应该能够得到正确的替换,而不是整个事情的单一替换。

也就是说,我也建议在这种情况下使用[^"]而不是。.

于 2013-07-07T17:09:45.847 回答
1

向前

确保您使用的是最新版本的记事本++,其中在记事本++ v5 中使用正则表达式的已知问题以及之前的问题已在 v6 中得到纠正。

基本的

尽管有很多正则表达式难以处理 HTML 的边缘情况,例如:

  • 属性可以在标签内以任意顺序出现
  • 属性的值可以看起来像实际的属性,例如<img onmouseover=' src="TheseAreNotTheDroidsYouAreLookingFor.png" ; funImageSwap(src); ' src="DecoyDroids.png">
  • 属性值可以使用单双引号或不使用引号

在您的表达中考虑将您的更改.+[^"]+. 这将防止正则表达式引擎离开引用区域或标签并进入下一个可能的匹配项

<img src="([^"]+)" border="([0-9]{1})" alt="([^"]*?)" width="([0-9]{2,3})" height="([0-9]{3})" style="float: (right|left);" />

但这并不能处理其他边缘情况。

复杂的

要绕过这些边缘情况,您可以使用这个怪物表达式。我把它放在多行上,并在此处发表评论以显示正在发生的事情,以帮助使其更容易理解。但是在记事本中,您需要删除注释和所有新行。

正则表达式

<img(?=\s|>)
(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\ssrc=('[^']*'|"[^"]*"|[^'"][^\s>]*)) # find src, capture value including quotes if they exist
(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\sborder=('[^']*'|"[^"]*"|[^'"][^\s>]*))  # find border, capture value including quotes if they exist
(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\salt=('[^']*'|"[^"]*"|[^'"][^\s>]*)) # find alt, capture value including quotes if they exist
(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\swidth=('[^']*'|"[^"]*"|[^'"][^\s>]*))   # find width, capture value including quotes if they exist
(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\sheight=('[^']*'|"[^"]*"|[^'"][^\s>]*))  # find height, capture value including quotes if they exist
(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\sstyle="[^"]*(float:\s*(?:right|left)))  # find style, capture value including quotes if they exist
[^>]*>                      # actually capture the string

用。。。来代替

<div class="imgContainer" style="$6;"><img src=$1 border=$2 alt=$3 width=$4 height=$5 /></div>

这是插入到我的记事本示例中的单行表达式。我正在使用记事本++ v6.3.3

<img(?=\s|>)(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\ssrc=('[^']*'|"[^"]*"|[^'"][^\s>]*))(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\sborder=('[^']*'|"[^"]*"|[^'"][^\s>]*))(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\salt=('[^']*'|"[^"]*"|[^'"][^\s>]*))(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\swidth=('[^']*'|"[^"]*"|[^'"][^\s>]*))(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\sheight=('[^']*'|"[^"]*"|[^'"][^\s>]*))(?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\sstyle="[^"]*(float:\s*(?:right|left)))[^>]*>

在此处输入图像描述

展开

  • <img匹配图像标签
  • (?=\s|>)向前看以确保图像标签名称后跟一个空格或右尖括号
  • (?=往前看,这个特定的找到了 src 属性,但其他所有的想法都是一样的。前瞻允许属性以任何顺序出现在标记内,因为在满足前瞻之后,正则表达式引擎返回到前瞻开始的位置并继续表达式的其余部分。
    • (?:非捕获组通过字符串移动正则表达式光标,跳过所有带引号的属性值。这是绕过可能被误认为是理想属性名称的属性值的魔法。
    • [^>=]匹配所有不是右括号或等号的字符
    • |或者
    • ='[^']*'匹配等号后跟单引号,单引号内的所有文本并关闭单引号
    • |或者
    • ="[^"]*"匹配等号后跟双引号,双引号内的所有文本并关闭双引号
    • |或者
    • =[^'"][^\s>]*等号后跟非引号字符,后跟任意数量的非空格或右尖括号字符
    • )*?关闭非捕获组,并允许它根据需要重复多次。捕获不会离开标签,因此如果不满足下一个条件,则此特定标签不是我们要查找的标签
  • \ssrc=匹配一个空格,后跟src=. 感谢上面的非捕获组,这只能是一个属性名称
  • (启动捕获组,这将获得 src 属性的值
    • '[^']*'匹配等号后跟单引号,单引号内的所有文本并关闭单引号
    • |或者
    • "[^"]*"匹配等号后跟双引号,双引号内的所有文本并关闭双引号
    • |或者
    • [^'"][^\s>]*等号后跟非引号字符,后跟任意数量的非空格或右尖括号字符
    • )关闭捕获组
  • )关闭前瞻
  • 这些 next lookahead 都遵循与上述 src 相同的逻辑
    • (?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\sborder=('[^']*'|"[^"]*"|[^'"][^\s>]*))查找边框,捕获包含引号的值(如果存在)
    • (?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\salt=('[^']*'|"[^"]*"|[^'"][^\s>]*))查找 alt,捕获包含引号(如果存在)的值
    • (?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\swidth=('[^']*'|"[^"]*"|[^'"][^\s>]*))查找宽度,捕获值,包括引号(如果存在)
    • (?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\sheight=('[^']*'|"[^"]*"|[^'"][^\s>]*))查找高度,捕获值,包括引号(如果存在)
    • (?=(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*?\sstyle="[^"]*(float:\s*(?:right|left)))find style, capture value 这个略有不同,因为实际属性值是如何匹配的
  • [^>]*>匹配 img 标记和右括号的其余部分,这可以防止正则表达式引擎意外找到包含的属性,该属性可能具有可能被误认为另一个 img 标记的值。
于 2013-07-07T16:15:40.483 回答