[英]Why this regex not giving expected output?
我有包含下面给出的一些值的字符串。 我想用一些新文本替换包含特定customerId的html img标签 。 我尝试了小的Java程序,它没有给我预期的输出。这是程序信息
我的输入字符串是
String inputText = "Starting here.. <img src=\"getCustomers.do?custCode=2&customerId=3334¶m1=123/></p>"
+ "<p>someText</p><img src=\"getCustomers.do?custCode=2&customerId=3340¶m2=456/> ..Ending here";
正则表达式是
String regex = "(?s)\\<img.*?customerId=3340.*?>";
我想放在输入字符串中的新文本
编辑开始:
String newText = "<img src=\"getCustomerNew.do\">";
编辑结束:
现在我在做
String outputText = inputText.replaceAll(regex, newText);
输出是
Starting here.. Replacing Text ..Ending here
但我的预期输出是
Starting here.. <img src=\"getCustomers.do?custCode=2&customerId=3334¶m1=123/></p><p>someText</p>Replacing Text ..Ending here
请注意,在我的预期输出中,仅将包含customerId = 3340的img标签替换为“替换文本”。 我不明白为什么在输出中我同时得到了两个img标签?
您在其中具有“通配符” /“任何”模式( .*
),它将匹配项扩展到可能的最长匹配字符串,并且模式中的最后一个固定文本为>
字符,因此与最后一个>
字符匹配在输入文本中,即最后一个!
您应该可以通过将.*
部分更改为[^>]+
类的内容来解决此问题,以使匹配不会超出第一个>
字符。
使用正则表达式解析HTML势必会引起麻烦。
正如其他人在评论中告诉您的那样,HTML不是常规语言,因此使用正则表达式进行操作通常很痛苦。 最好的选择是使用HTML解析器。 我以前没有使用过Jsoup,但是在谷歌搜索了一下之后,您似乎需要这样的东西:
import org.jsoup.*;
import org.jsoup.nodes.*;
import org.jsoup.select.*;
public class MyJsoupExample {
public static void main(String args[]) {
String inputText = "<html><head></head><body><p><img src=\"getCustomers.do?custCode=2&customerId=3334¶m1=123\"/></p>"
+ "<p>someText <img src=\"getCustomers.do?custCode=2&customerId=3340¶m2=456\"/></p></body></html>";
Document doc = Jsoup.parse(inputText);
Elements myImgs = doc.select("img[src*=customerId=3340");
for (Element element : myImgs) {
element.replaceWith(new TextNode("my replaced text", ""));
}
System.out.println(doc.toString());
}
}
基本上,代码获取具有包含给定字符串的src
属性的img
节点列表。
Elements myImgs = doc.select("img[src*=customerId=3340");
然后遍历列表,并用一些文本替换那些节点。
UPDATE
如果您不想将整个img
节点替换为文本,而是需要为其src
属性赋予一个新值,则可以将for
循环的块替换for
:
element.attr("src", "my new value"));
或者,如果您只想更改src
值的一部分,则可以执行以下操作:
String srcValue = element.attr("src");
element.attr("src", srcValue.replace("getCustomers.do", "getCustonerNew.do"));
这与我在此主题中发布的内容非常相似。
发生的情况是,您的正则表达式开始与第一个img标签匹配,然后消耗所有内容(无论是否贪婪),直到找到customerId = 3340 ,然后继续消耗所有内容,直到找到>为止。
如果您只想使用customerId = 3340的img ,请考虑一下此标签与可能匹配的其他标签有何不同。
在这种特殊情况下,一种可能的解决方案是使用后向运算符(不消耗匹配项)查看img标记后面的内容。 此正则表达式将起作用:
String regex = "(?<=</p>)<img src=\".*?customerId=3340.*?>";
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.