我正试图在一个特定的场景中使用regex,如下所述:
有许多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>
我们针对模式"/<anything>/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>
正则表达式中最大的错误是使用方括号。在正则表达式中,[abc]
匹配一个字符,即a
、b
或c
;它与子串CCD_ 8不匹配。所以[/images/]
不会做你认为它会做的事情。拆下方括号。
您的正则表达式实际发生了什么:
"{1}(.){1,}[/images/]{1}
它将匹配一个引号字符,后跟一个或多个任意字符,后跟字符/
、i
、m
、a
、g
、e
、s
之一。(最后一个/
将被忽略,因为集合中已经有一个。)此外,当您告诉它匹配任何字符的一个或多个出现时,默认情况下,它会进行贪婪匹配,匹配尽可能多的字符。因此,它将停止在方括号中最远的字符,而不是最近的字符;最远的字符是CCD_ 19中的CCD_。
试试这个正则表达式:
".+?/images/
您永远不需要告诉正则表达式与{1}
恰好匹配一次;它会自动为你做到这一点。CCD_ 21是CCD_。?
告诉regex匹配最少的字符数,而不是最大的字符数。然后它将查找最近的/images/
子字符串。
如果你想要替换的所有位置实际上总是相同的,比如说你想要用img/a.png
替换assets/images/somefolder/a.png
,你可以很容易地在你拥有的字符串上使用替换方法,所以在你的情况下可能是带子字符串的东西?
如果这看起来很简单,那么使用regex就是严重的过度使用。试试这个
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