当前位置: 代码迷 >> Java相关 >> Java正则匹配反义字符串有关问题
  详细解决方案

Java正则匹配反义字符串有关问题

热度:58   发布时间:2016-04-22 19:37:40.0
Java正则匹配反义字符串问题
我在做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);

------解决思路----------------------
引用:
Quote: 引用:

擦,写错了不能编辑。cdsn太龊了。其实“//当img里的alt不是以-i结尾,则匹配到符合这个条件的第一个img,并修改这个img里的alt属性值”这段注释应该是if后面而不是在for后面。。。

Quote: 引用:

使用{2}而不能{1}的原因是根据你要匹配的目标字符串有关。你要求属性值【-2】结尾的attr不匹配。采用非捕获组正则【(?! X)】是不占字符位的。加个【.{2}】主要目的是要占着这2个空位,防止【[^\"]*】将这2个空位也一起匹配掉了。加上后【[^\"]*】匹配时到【-2】就会停止继续往下。而最后这2个占位留下来的目标,就是为了匹配【-2】,如果匹配中了。就说明【(?!-2)】不成立,即你提供的那个串中的第一个attr不会被匹配到,即不会被替换。而后一个attr就会被匹配并替换

吐槽下CSDN,web端的论坛即卡,插件又常出问题。现在用客户端回复。【】括号,及其内容,竟然全被过滤掉了

靠,确实是啊,我居然忘了{}的作用了,擦。真是不好意思,只不过csdn不能连续回复3次以上,也不能编辑回复,我也要吐槽。。。我再看看你这个。。

只不过你这个和rui888一样也不能匹配alt=""的情况呢,我的思路是想只要alt里没有匹配-i"这个字符串的就可以被替换,例如alt="xxx-1"、alt="xxx-2"、alt="xxx-3"都不能匹配,但alt="xxx-"、alt="xxx2"、alt=""、alt="xxx"、alt="xx-2xxx"、alt="-2xxx"等都要被替换掉

【"alt=\"[^\"]*\"(?<!-\\d\")"】,前端问号【?】描述有误:表示0或1次。
  相关解决方案