大虾帮助看下,这个java正则表达式哪里写错了?

网络科技 2012-12-21 08:49:39
先看代码:

public static void main(String[] args){
String str = "ab<style type=\"text/css\" > .?[]cd*{ss}\r\n body {ef}gh{} body , table{ij} kl</style>mn";
String reg = "<style[\\s][\\s\\S]*?>[\\s\\S]*?([\\s][b][o][d][y][\\s\\S]*?\\{[\\s\\S]*?\\})|([b][o][d][y][\\s]*?,)[\\s\\S]*?<\\/[s][t][y][l][e]>";
System.out.println("替换结果:"+str.replaceAll(reg, ""));//值为:abgh{} mn,不是我想要的
}

先简单说明下:
我想实现的功能是找出字符串中位于<style>标签类的body{...}与body, 并把这两个用空串代替。
实例代码中,我想要的替换结果是:

"ab<style type=\"text/css\" > .?[]cd*{ss}\r\n gh{} table{ij} kl</style>mn"
即把:
"ab<style type=\"text/css\" > .?[]cd*{ss}\r\n body {ef}gh body , table{ij} kl</style>mn";
红色部分替掉。
为避免复杂起见,约定str字符只有一对<style>标签,body前后只允许为空格或,{ 即取body后逗号为止和取body后第一对{}为止,用""代替换
上文应该说得比较清楚了,本人正则运用不熟,请大虾指教,谢了
...全文
532 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
chen2713756 2012-12-24
  • 打赏
  • 举报
回复
引用 17 楼 xzy88 的回复:
引用 16 楼 brightyq 的回复: 首先你的字符串有个问题,里面有\r\n,回车换行,所以打印出来的str是占两行的 把\r\n改成\\r\\n 然后正则如下: Java code?1234567891011121314151617import java.util.regex.Matcher;import java.util.regex.Pattern; public cl……
这个正则表达式确实挺好,不过少了一个地方,就是body后面那个逗号了,最后结果没替换掉。还有就是如果这个你的字符串是写死了,就是你给出的这个字符串,不再包含其他的<style></style>标签,的确OK。如果字符串有所修改,最后循环替换的结果就有问题了。另外还想说一下,你这个问题的要求是有点苛刻,应该是你自己想出来的一个问题吧,不排除有完美的正则表达式,在字符串随便被定义的情况下也能达到你的要求,但是花时间研究像这样匹配难度比较大的正则表达式,还不如用代码老老实实弄出来~
brightyq 2012-12-23
  • 打赏
  • 举报
回复
首先你的字符串有个问题,里面有\r\n,回车换行,所以打印出来的str是占两行的 把\r\n改成\\r\\n 然后正则如下:
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexText {

	public static void main(String[] args) {
		String str = "ab<style type=\"text/css\" >.?[]cd*{ss}\\r\\n body {ef}gh{} body , table{ij} kl</style>mn";
		String regex = "(.*<style.*)(body\\s(\\{.*?\\})?)(.*</style>.*)";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(str);
        while(m.find()){
        	str = str.replaceAll(regex, "$1$4");
        	m.reset(str);        
        }
        System.out.println(str);
	}
}
网络科技 2012-12-23
  • 打赏
  • 举报
回复
引用 16 楼 brightyq 的回复:
首先你的字符串有个问题,里面有\r\n,回车换行,所以打印出来的str是占两行的 把\r\n改成\\r\\n 然后正则如下: Java code?1234567891011121314151617import java.util.regex.Matcher;import java.util.regex.Pattern; public class RegexT……
测试了下,这个是正确的,符合要求,感谢大虾,结了
程序员一灯 2012-12-22
  • 打赏
  • 举报
回复
真对不起。回答错了。
网络科技 2012-12-22
  • 打赏
  • 举报
回复
引用 10 楼 chen2713756 的回复:
正解如下: String str = "ab<style type=\"text/css\" > .?[]cd*{ss}\r\n body {ef}gh{} body , table{ij} kl</style>mn"; String reg = "([b][o][d][y])+( [{]\\w*[}])*"; System.out.println("替换结果:"+……
你这个还是不正确啊 结果是:ab<style type="text/css" > .?[]cd*{ss} gh{} , table{ij} kl</style>mn 很明显,还有一个,号没去掉。 并且,你没有指定是在<style>标签内,即,<style>标签外,有body, body{...},也会被替换成空串,这显然不合我意思啊。 String str = "ab<style type=\"text/css\" > .?[]cd*{ss}\r\n body {ef}gh{} body , table{ij} kl</style>mn body {ef}";//红色是在外面的,要保留,不然的话,没什么难度了 这个字符串的结果应该为:"ab<style type=\"text/css\" > .?[]cd*{ss}\r\n gh{} table{ij} kl</style>mn body {ef}"
chen2713756 2012-12-22
  • 打赏
  • 举报
回复
正解如下: String str = "ab<style type=\"text/css\" > .?[]cd*{ss}\r\n body {ef}gh{} body , table{ij} kl</style>mn"; String reg = "([b][o][d][y])+( [{]\\w*[}])*"; System.out.println("替换结果:"+str.replaceAll(reg, ""));
笑莫问 2012-12-22
  • 打赏
  • 举报
回复
来学习了。
网络科技 2012-12-22
  • 打赏
  • 举报
回复
引用 8 楼 zhou9898 的回复:
真对不起。回答错了。
呵,你真客气,没事啦,重在参与啊,多学点知识,也祝你进步。。。 有新的灵感,也欢迎再来解答
网络科技 2012-12-22
  • 打赏
  • 举报
回复
估计确实有点难度,看来只能先用折中的办法了,先不要求在<style>标签间了。。。 这样可用:reg = "([\\s][b][o][d][y][\\s]*?\\{[\\s\\S]*?\\})|([\\s][b][o][d][y][\\s]*?,)"; 本贴个先不结再放些天吧,看下,有没那位高人能解决只匹配<style>标签间的情况
网络科技 2012-12-22
  • 打赏
  • 举报
回复
引用 12 楼 chen2713756 的回复:
下午看到你说我的回复不对,的确是不合你的要求,上午没太仔细看你的要求,这会有点闲时间又写了一下,不过还是花了一个多小时,呵呵!!! public static void main(String[] args) { String str = "ab<style type=\"text/css\" > .?[]cd*{ss}\r\n body {ef}gh{} body ……
老兄,你这也太复杂了啊,应该可以一步到位吧? 正则应该一步不至于搞不定啊,我认为,还是我的正则水平不够。 不过,还是很感谢你花这么多时间去研究啊,为表谢意,到时至少给你20分啦 我加分了,真正完美解决的那位100分,另一百分,按功劳适当给,参与的都有分吧,这也是我的原则。 当然,也不是说拿分说事,也是一种形式吧。。。。
chen2713756 2012-12-22
  • 打赏
  • 举报
回复
下午看到你说我的回复不对,的确是不合你的要求,上午没太仔细看你的要求,这会有点闲时间又写了一下,不过还是花了一个多小时,呵呵!!! public static void main(String[] args) { String str = "ab<style type=\"text/css\" > .?[]cd*{ss}\r\n body {ef}gh{} body , table{ij} kl</style>mn body {ef}"; // 转换字符串中的\r\n str = str.replaceAll("\n", "\\\\n").replaceAll("\r", "\\\\r"); String strClone = str; System.out.println("原来的字符串"+str); // 定义替换的正则表达式 String reg = "([b][o][d][y])+( [{]\\w*[}]| ([,.?!]*))*"; int a = 0; // 一对完整的标签的起始位置 int b = 0; // 一对完整的标签的结束位置 List<String> list1 = new ArrayList<String>(); // 接收所有成对标签及所包含的内容 List<String> list2 = new ArrayList<String>(); // 接收所有不在标签内的内容 // 如果字符串不是以标签开始 if (str.indexOf("<style") != 0) { list2.add(str.substring(0, str.indexOf("<style"))); } // 如果字符串中包含有标签 while (str.contains("style")) { a = str.indexOf("<style"); // 获得从当前字符串的第一个标签开始到结束的字符串 String subStr = str.substring(a); b = subStr.indexOf("</style>"); // 获得当前字符串中第一对标签所包含的内容并替换 String subString = str.substring(a, a + b + 8).replaceAll(reg, ""); list1.add(subString); // 重新定义字符串的内容为:从第一对标签结束起,到字符串结束止 str = str.substring(a + b + 8); // 如果字符串不是以标签结束,截取所有 if (str.indexOf("<style") == -1 && str.length() != 0) { list2.add(str.substring(0)); } else { list2.add(str.substring(0, str.indexOf("<style"))); } } // //输出两个集合的参数 // for (int i = 0; i < list1.size(); i++) { // System.out.println(list1.get(i)); // } // for (int i = 0; i < list2.size(); i++) { // System.out.println(list2.get(i)); // } // System.out.println(list1.size()); // System.out.println(list2.size()); // 定义StringBuffer对象,重新组合字符串 StringBuffer sb = new StringBuffer(); // 标签字符串的个数大于等于非标签字符串的个数 if (list1.size() >= list2.size()) { // 字符串以标签开头 if (strClone.indexOf("<style") == 0) { for (int i = 0; i < list2.size(); i++) { sb.append(list1.get(i)); sb.append(list2.get(i)); } for (int i = list2.size(); i < list1.size(); i++) { sb.append(list1.get(i)); } } else { for (int i = 0; i < list2.size(); i++) { sb.append(list2.get(i)); sb.append(list1.get(i)); } for (int i = list2.size(); i < list1.size(); i++) { sb.append(list1.get(i)); } } } else if (list1.size() < list2.size()) { // 当前条件是标签字符串的个数小于非标签字符串的个数,字符串的格式一定是非标签字符串开头和结尾 for (int i = 0; i < list1.size(); i++) { sb.append(list2.get(i)); sb.append(list1.get(i)); } for (int i = list1.size(); i < list2.size(); i++) { sb.append(list2.get(i)); } } System.out.println("替换后字符串"+sb); }
网络科技 2012-12-21
  • 打赏
  • 举报
回复
找到:body{...}与body,这有个限定条件,是要必须在<style></style>标签间的才行,换句话说,在这之外,是不能被替换为空串的<style>body{...}body,</style>body,body{...} 结果为:<style></style>body,body{...}是正确的,而为: <style></style>就错了。。。。 休息去了,改天再试了。。。
网络科技 2012-12-21
  • 打赏
  • 举报
回复
引用 3 楼 zhou9898 的回复:
Java code?1String regex = "body|\\{ef\\}"; 这个貌似也行。。。
不是貌似也行,而是肯定不行啊,少了<style></style>body{}body, 这些字符,一看就知道不对了,呵 看来,你应该也是初学正则吧,我也是现学现用,不过,是好久以前学的,老是会忘记,还是等正则高人前来救场吧
网络科技 2012-12-21
  • 打赏
  • 举报
回复
引用 2 楼 zhou9898 的回复:
Java code?1234String str = "ab<style type=\"text/css\" > .?[]cd*{ss}\r\n body {ef}gh{} body , table{ij} kl</style>mn";String regex = "body \\{ef\\}gh\\{\\} body";str = str.replaceAll(rege……
呵,不容易啊,正准备去休息了,终于见到有人回复了。。。 不过,你这个写法,一看就知道不可行呢。表达式里,怎么可能出现ef,gh呢,这个是代表任何的字符啊,用.*?或用[\\s\\S]*?代替才行吧? 再说补充下吧,表过式里,固定字符是:<style></style>body{}body, 其它的,都要用可变的 还有,你替换那里也写错了,是用空串替换,不是用"gh{}"啊 今晚放假了,估计大虾们也都忙喝酒交际去了呢,先去休息再说吧 对正则有兴趣的同学,也欢迎拷去研究吧
程序员一灯 2012-12-21
  • 打赏
  • 举报
回复
最多只能回复3条。 给楼主个正则表:

验证数字的正则表达式集 
空格:.
验证数字:^[0-9]*$
验证n位的数字:^\d{n}$
验证至少n位数字:^\d{n,}$
验证m-n位的数字:^\d{m,n}$
验证零和非零开头的数字:^(0|[1-9][0-9]*)$
验证有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
验证有1-3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
验证非零的正整数:^\+?[1-9][0-9]*$
验证非零的负整数:^\-[1-9][0-9]*$
验证非负整数(正整数 + 0)  ^\d+$
验证非正整数(负整数 + 0)  ^((-\d+)|(0+))$
验证长度为3的字符:^.{3}$
验证由26个英文字母组成的字符串:^[A-Za-z]+$
验证由26个大写英文字母组成的字符串:^[A-Z]+$
验证由26个小写英文字母组成的字符串:^[a-z]+$
验证由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
验证由数字、26个英文字母或者下划线组成的字符串:^\w+$
验证用户密码:^[a-zA-Z]\w{5,17}$ 正确格式为:以字母开头,长度在6-18之间,只能包含字符、数字和下划线。
验证是否含有 ^%&',;=?$\" 等字符:[^%&',;=?$\x22]+
验证汉字:^[\u4e00-\u9fa5],{0,}$
验证Email地址:^[A-Za-z](\w+[-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$ 正确格式:
验证InternetURL:^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$ ;^[a-zA-z]+://(w+(-w+)*)(.(w+(-w+)*))*(?S*)?$
验证电话号码:^(\(\d{3,4}\)|\d{3,4}-)?\d{7,8}$:--正确格式为:XXXX-XXXXXXX,XXXX-XXXXXXXX,XXX-XXXXXXX,XXX-XXXXXXXX,XXXXXXX,XXXXXXXX。
验证身份证号(15位或18位数字):^\d{15}|\d{}18$
验证一年的12个月:^(0?[1-9]|1[0-2])$ 正确格式为:“01”-“09”和“1”“12”
验证一个月的31天:^((0?[1-9])|((1|2)[0-9])|30|31)$    正确格式为:01、09和1、31。
整数:^-?\d+$
非负浮点数(正浮点数 + 0):^\d+(\.\d+)?$
正浮点数   ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
非正浮点数(负浮点数 + 0) ^((-\d+(\.\d+)?)|(0+(\.0+)?))$
负浮点数  ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
浮点数  ^(-?\d+)(\.\d+)?

推荐本书: 《正则应知必会》、《正则必知必会》
程序员一灯 2012-12-21
  • 打赏
  • 举报
回复

String regex = "body|\\{ef\\}";
这个貌似也行。。。
程序员一灯 2012-12-21
  • 打赏
  • 举报
回复

		String str = "ab<style type=\"text/css\" > .?[]cd*{ss}\r\n body {ef}gh{} body , table{ij} kl</style>mn";
		String regex = "body \\{ef\\}gh\\{\\} body";
		str = str.replaceAll(regex, "gh{}");
		System.out.println(str);
偷懒的不知道行不行呀。。 呵呵。。。我在继续想。。。等会还会恢复。
网络科技 2012-12-21
  • 打赏
  • 举报
回复
有人懂不? 试了好久,还是没弄出来,感觉那个表达式没什么问题啊, 坐等大虾指教。。。。

81,094

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧