我在做seo的时候遇到一个用正则排除字符串的问题,想请教下同仁们
String str = "<p><img alt=\"sdfasdf\" src=\"http://www.yb-test.com/upload/2014-06-20/333/images/1403662550878.jpg\" style=\"height:189px; width:304px\" /></p>\r<p><img alt=\"\" src=\"http://www.yb-test.com/upload/2014-06-20/333/images/1403662550878.jpg\" style=\"height:189px; width:304px\" /></p>\r<p>大似的发的说法</p>\r<p><img src=\"http://www.yb-test.com/upload/2014-06-20/333/images/1403771804592.jpg\" style=\"height:408px; width:750px\" /></p>\r<p>大都市发生的发生的发生的泛</p>\r<p><img src=\"http://www.yb-test.com/upload/2014-06-20/333/images/1407738076985.jpg\" alt=\"fasdf\" style=\"height:321px; width:750px\" /></p>";
str是原始数据,我想最终控制台能输出如下数据(其中转义和换行我就不细说了,想必大家都懂的)
<p><img alt="标题-1" src="http://www.yb-test.com/upload/2014-06-20/333/images/1403662550878.jpg" style="height:189px; width:304px" /></p>
<p><img alt="标题-2" src="http://www.yb-test.com/upload/2014-06-20/333/images/1403662550878.jpg" style="height:189px; width:304px" /></p>
<p>大似的发的说法</p>
<p><img alt="标题-3" src="http://www.yb-test.com/upload/2014-06-20/333/images/1403771804592.jpg" style="height:408px; width:750px" /></p>
<p>大都市发生的发生的发生的泛</p>
<p><img src="http://www.yb-test.com/upload/2014-06-20/333/images/1407738076985.jpg" alt="标题-4" style="height:321px; width:750px" /></p>
我在做的时候遇到了怎么去过滤反义字符串的问题,即我想过滤掉alt=".*-i"的img
测试代码如下
//测试数据a 预想值=获取值
String a = "<p><img alt=\"dfad-2sf-\" src=\"http://.jpg\" style=\"width:304px\" /></p> ";
System.out.println("预想值a:<p><img OK src=\"http://.jpg\" style=\"width:304px\" /></p>"+
"\r获取值a:"+a.replaceAll("alt=\".*?\"", "OK"));
//测试数据b 预想值!=获取值 此正则与上一个相比,感觉"?"不起作用了,居然把src属性也给替换了,这是不解之一
String b = "<p><img alt=\"dfad-2sf-2\" src=\"http://.jpg\" style=\"width:304px\" /></p>";
System.out.println("预想值b:<p><img OK src=\"http://.jpg\" style=\"width:304px\" /></p>"+
"\r获取值b:"+b.replaceAll("alt=\".*[-2]?\"", "OK"));
//测试数据c 预想值!=获取值 此正则不知道如何排除掉第一个img,而只替换掉第二个img里的alt属性,这是不解之二
String c = "<p><img alt=\"标题-2\" src=\"http://.jpg\" style=\"width:304px\" /></p>\r<p><img alt=\"fasdfafd\" src=\".jpg\" style=\"width:304px\" /></p>";
System.out.println("预想值c:<p><img alt=\"标题-2\" src=\"http://.jpg\" style=\"width:304px\" /></p>\r<p><img OK src=\".jpg\" style=\"width:304px\" /></p>"+
"\r获取值c:"+c.replaceFirst("alt=\".*(?!-2)?\"", "OK"));
//不解之三,不知道该如何去分析一个正则表达式为何不能达到自己想要的结果。。。
//希望各位大神能帮忙一下
------解决思路----------------------
1.不解之一
原因:[-2]?表示0到多个“-2”,alt=\"【dfad-2sf-2\" src=\"http://.jpg\" style=\"width:304px】\" ,注意【】括起的部分就是.*正则匹配到的。
修正:去掉“?”
2.不解之二
首先先去掉正则中的问号,原因如第1个疑问说的。如alt=\"【标题-2\" src=\"http://.jpg\" style=\"width:304px】\",会被匹配。
对于(?! X)作为非捕获组正则需要注意一个问题,匹配的串尾是允许以X结尾的,只要串满足(?! X)前的正则。如alt=\"【标题-2】\" 如【】括起的串“标题-2”满足【.*】这个则正则。而且其后已没有字符(满足,后面没有出现-2字符)。
修正:正则修改为【"alt=\"[^\"]*(?!-2).{2}\""】
3.不解之三
关于验证正则准确性的建议:
1、打好正则知识基础(PS:正则的技术不是java独有的,是独立的一门技术,没那么简单全面掌握,一堆算法。市面上也有专门讲正则的书籍),建议深入学习下。
2、自己利用java现有API写代码验证, 或者利用一些正则插件验证(网上百度下吧)。推荐后者。
------解决思路----------------------
String str = "<p><img alt=\"sdfasdf\" src=\"http://www.yb-test.com/upload/2014-06-20/333/images/1403662550878.jpg\" style=\"height:189px; width:304px\" /></p>\r<p><img alt=\"\" src=\"http://www.yb-test.com/upload/2014-06-20/333/images/1403662550878.jpg\" style=\"height:189px; width:304px\" /></p>\r<p>大似的发的说法</p>\r<p><img src=\"http://www.yb-test.com/upload/2014-06-20/333/images/1403771804592.jpg\" style=\"height:408px; width:750px\" /></p>\r<p>大都市发生的发生的发生的泛</p>\r<p><img src=\"http://www.yb-test.com/upload/2014-06-20/333/images/1407738076985.jpg\" alt=\"fasdf\" style=\"height:321px; width:750px\" /></p>";
Matcher m=Pattern.compile("\\s+alt=\"(.*?)\"\\s+").matcher(str);
int i=1;
while(m.find()){
str=str.replace("alt=\""+m.group(1)+"\"", "alt=\"标题-"+i+"\"");
i++;
}
System.out.println(str);
------解决思路----------------------
【"alt=\"[^\"]*\"(?<!-\\d\")"】,前端问号【?】描述有误:表示0或1次。