【问题标题】:regex to modify dynamic src attributes正则表达式修改动态 src 属性
【发布时间】:2014-12-03 17:55:06
【问题描述】:

我正在尝试在特定场景中使用正则表达式,如下所述:

有许多 HTML 页面,每个页面都包含多个具有动态值的 <img src> 标签:

Tag1 = <p>Para1 <img src="/A/images/b.txt">Some text</p>   
Tag2 = <p>Para2 <img src="/A/B/images/c.jpeg">Some text</p>  
Tag3 = <p>Para3 <img src="/../images/H/e.png">Some text</p> 
Tag4 = <p>Para4 <img src="/../D/images/G/J/f.gif">Some text</p>

我们的目标是模式"/&lt;anything&gt;/images/。更换后我们需要的是

Tag1 = <p>Para1 <img src="/library/MYFOLDER/location/b.txt">Some text</p>
Tag2 = <p>Para2<img src="/library/MYFOLDER/location/c.jpeg">Some text</p>
Tag3 = <p>Para3<img src="/library/MYFOLDER/location/H/e.png">Some text</p>
Tag4 = <p>Para4<img src="/library/MYFOLDER/location/G/J/f.gif">Some text</p>

实际发生的情况非常不同。模式是在/images 之后吃掉所有东西并给我们

Tag1 = <p>Para1 <img src="/library/MYFOLDER/locationp>
Tag2 = <p>Para2<img src="/library/MYFOLDER/locationp>
Tag3 = <p>Para3<img src="/library/MYFOLDER/locationp>
Tag4 = <p>Para4<img src="/library/MYFOLDER/locationp>

这是我正在使用的正则表达式模式

"{1}(.){1,}[/images/]{1}<br>

代码如下:

String subStringTem = "<p><strong>Control Steps:</strong> <img src=\"../images/retain_image.gif\" width=\"20\" > Description.</p>";
String newImagPath = "\"/library/MYFOLDER/location";
final Pattern p = Pattern.compile("\"{1}(.){1,}[/images/]{1}");
final Matcher m = p.matcher(subStringTem);
String result = m.replaceAll(newImagPath);
System.out.println(result);

预期结果:

<p><strong>Control Steps:</strong> <img src="/library/MYFOLDER/location/retain_image.gif\" width=\"20\" > Description.</p> 

实际结果:

<p><strong>Control Steps:</strong> <img src="/library/MYFOLDER/locationp>

【问题讨论】:

  • [/images/] 在正则表达式中匹配 一个 字符,即/image ,或s(最后一个 / 是多余的)。如果要匹配序列,请删除方括号。此外,正则表达式中永远不需要{1}{1,} 更简洁地表示为+。我认为您应该查看有关正则表达式的教程,例如this one

标签: java html regex


【解决方案1】:

您的正则表达式中最大的错误是使用方括号。在正则表达式中,[abc] 匹配abc 的一个字符;它与子字符串 "abc" 不匹配。所以[/images/] 并没有按照你的想法去做。去掉方括号。

你的正则表达式实际发生了什么:

"{1}(.){1,}[/images/]{1}

它将匹配一个引号字符,后跟 1 次或多次出现的任何字符,然后是 /images。 (最后一个 / 将被忽略,因为您已经在集合中找到了一个。)此外,当您告诉它匹配任何字符的一个或多个出现时,默认情况下它会进行 greedy 匹配,匹配尽可能多的字符。因此,它将停在方括号中最远的字符处,而不是最近的字符处;最远的字符是&lt;/p&gt; 中的/

试试这个正则表达式:

".+?/images/

您永远不需要告诉正则表达式与{1} 精确匹配一次;它会自动为您做到这一点。 +{1,} 的简写。 ? 告诉正则表达式匹配最少数量的字符,而不是它可以匹配的最大数量。然后它会寻找最近的/images/子串。

【讨论】:

  • 非常感谢 ajb 的精彩解释。我对正则表达式非常陌生,并且正在同时学习教程,但客户端时间线非常严格。我保证我会完成所有的教程,并会提高我在这方面的技能。再次感谢您!
【解决方案2】:

如果您要替换的所有位置实际上总是相同的,即假设您想用img/a.png 替换assets/images/somefolder/a.png,您可以很容易地在您拥有的字符串上使用replace 方法,所以在你的情况下 也许有子字符串?

如果这看起来很简单,那么使用正则表达式是非常过分的。 试试这样的

String src = "/A/images/b.txt";
String othersrc = "/library/MYFOLDER/";
//remove everything from before /images/ and replace it with your path
src = othersrc + src.substring(src.lastIndexOf("/images/") + 1, src.length());
System.out.println(src);

结果:
/library/MYFOLDER/images/b.txt

【讨论】:

  • 感谢 zack 的回复,但我们不想删除“/images”之前的所有内容。读取的字符串包含完整的行,其中包含“src”作为包含“/images”的部分。请看我上面解释的例子。
猜你喜欢
  • 1970-01-01
  • 2012-04-10
  • 2014-04-14
  • 1970-01-01
  • 1970-01-01
  • 2012-05-26
相关资源
最近更新 更多