[quote][size=medium] 做信息采集时,难免要用到一些正则表达式了。但是用正则表达式有个贪婪性问题。
贪婪量词先看整个字符串是不是匹配,如果没有发现匹配,先去掉最后字符串中的最后一个字符,并再次尝试,如果还没有发现匹配,那么再次去掉最后一个字符,这个过程会一直重复下去直到发现匹配或不剩任何字符串,上面的简单量词都是贪婪量词。
惰性量词先看字符串中的第一个字母是不是一个匹配,如果不匹配则继续读入下一个字符进行匹配,如果没有则一直匹配下去,与贪婪量词刚好相反,惰性量词用上面的简单量词跟一个?表示。
支配量词只尝试匹配整个字符串,如果整个字符串不能匹配,不能进一步尝试。
运用前瞻可以告诉正则表达式运算器向前看一些字符而不移动其位置,包括正向前瞻和负向前瞻,正向前瞻检查的是接下来出现的是不是某个特定字符集,而负向 前瞻则是检查接下来的不应该出现的特定字符集。创建正向前瞻要将模式放在(?=和)之间。创建负向前瞻要将模式放在(?!和)之间。
下面我做了个例子来解决下这个问题。主要是用 贪婪限定符 ‘?’。
[/size][/quote]
贪婪量词先看整个字符串是不是匹配,如果没有发现匹配,先去掉最后字符串中的最后一个字符,并再次尝试,如果还没有发现匹配,那么再次去掉最后一个字符,这个过程会一直重复下去直到发现匹配或不剩任何字符串,上面的简单量词都是贪婪量词。
惰性量词先看字符串中的第一个字母是不是一个匹配,如果不匹配则继续读入下一个字符进行匹配,如果没有则一直匹配下去,与贪婪量词刚好相反,惰性量词用上面的简单量词跟一个?表示。
支配量词只尝试匹配整个字符串,如果整个字符串不能匹配,不能进一步尝试。
运用前瞻可以告诉正则表达式运算器向前看一些字符而不移动其位置,包括正向前瞻和负向前瞻,正向前瞻检查的是接下来出现的是不是某个特定字符集,而负向 前瞻则是检查接下来的不应该出现的特定字符集。创建正向前瞻要将模式放在(?=和)之间。创建负向前瞻要将模式放在(?!和)之间。
下面我做了个例子来解决下这个问题。主要是用 贪婪限定符 ‘?’。
[/size][/quote]
package slcx.com.example;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
* 这里是用来检测正则表达式的贪婪性。
*
* @author LoongHua
*
*/
public class T {
public static void getDefaulst(){
//这里得到默认的那个'XX'及其下一个字符的正则表达式
String regex = ".*(XX.).*";
String s="..aaXXbbXXccXXddXXee..";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(s);
if (matcher.matches()) {
System.out.println("默认情况下的结果:"+matcher.group(1));
}
}
public static void getFirst(){
//我们这里得到第一个'XX'及其下一个字符的正则表达式
String regex = ".*?(XX.).*";
String s="..aaXXbbXXccXXddXXee..";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(s);
if (matcher.matches()) {
System.out.println("得到第一个的结果:"+matcher.group(1));
}
}
public static void getLast(){
String regex = ".*(XX.).*?";
String s="..aaXXbbXXccXXddXXee..";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(s);
if (matcher.matches()) {
System.out.println("得到最后一个的结果:"+matcher.group(1));
}
}
/**
* 得到网页中的时间问题
*/
public static void getDateTime(){
String html="更新时间:2009-3-23 13:14:31 作 者更新时间:2009-3-23 13:12:54 作 者更新时间:2009-3-16 17:39:54作 者更新时间:2009-3-13 9:07:22作 者更新时间:2009-3-9 13:41:51作 者更新时间:2009-3-5 11:19:36作 者更新时间:2009-3-5 11:16:33作 者更新时间:2009-3-2 11:56:21作 者更新时间:2009-2-26 10:30:19作 者更新时间:2009-2-26 10:28:49更新时间";
// 这个正则表达式能抓取很多类型的日期时间,小到只有日期,大到日期时间(包括秒),这里是默认情况下提取。
//String regex=".*[^\\d]((\\d{4}|\\d{2}) ?[/年-] ?\\d{1,2} ?[/月-] ?\\d{1,2} ?[日 ]?( ?\\d{1,2}( ?[点:] ?\\d{1,2}( ?[分:] ?\\d{1,2} ?秒?)?)?)?)[^\\d].*";
//这里使用了贪婪限定符 ? 提取第一个时间
String regex=".*?[^\\d]((\\d{4}|\\d{2}) ?[/年-] ?\\d{1,2} ?[/月-] ?\\d{1,2} ?[日 ]?( ?\\d{1,2}( ?[点:] ?\\d{1,2}( ?[分:] ?\\d{1,2} ?秒?)?)?)?)[^\\d].*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(html);
if (matcher.matches()) {
System.out.println("得到第一个的时间是:"+matcher.group(1));
}
//这里使用了贪婪限定符 ? 提取最后一个时间
regex=".*[^\\d]((\\d{4}|\\d{2}) ?[/年-] ?\\d{1,2} ?[/月-] ?\\d{1,2} ?[日 ]?( ?\\d{1,2}( ?[点:] ?\\d{1,2}( ?[分:] ?\\d{1,2} ?秒?)?)?)?)[^\\d].*?";
pattern = Pattern.compile(regex);
matcher = pattern.matcher(html);
if (matcher.matches()) {
System.out.println("得到最后一个的时间是:"+matcher.group(1));
}
}
/**
* 当网页中有多个日期时间时,我们又不要开始结尾的日期时间时
*
* 这个时候我们时候就不能完全用正则来实现了(可能可以,只是我不知道而已)
*
* @param index 指定要第几个日期时间。
*/
public static void getDateTime(int index){
String regex="((\\d{4}|\\d{2}) ?[/年-] ?\\d{1,2} ?[/月-] ?\\d{1,2} ?[日 ]?( ?\\d{1,2}( ?[点:] ?\\d{1,2}( ?[分:] ?\\d{1,2} ?秒?)?)?)?)[^\\d].*";
String html="更新时间:2009-3-23 13:14:31 作 者更新时间:2009-3-23 13:12:54 作 者更新时间:2009-3-16 17:39:54作 者更新时间:2009-3-13 9:07:22作 者更新时间:2009-3-9 13:41:51作 者更新时间:2009-3-5 11:19:36作 者更新时间:2009-3-5 11:16:33作 者更新时间:2009-3-2 11:56:21作 者更新时间:2009-2-26 10:30:19作 者更新时间:2009-2-26 10:28:49更新时间";
Pattern pattern = Pattern.compile(regex);
int count=0;
while(html.length()>0){
Matcher matcher = pattern.matcher(html);
if (matcher.matches()) {
count++;
if(count==index){
System.out.println("得到第 "+index+" 个的时间是:"+matcher.group(1));
}
else{
html=html.substring(matcher.group(1).length());
}
}
else{
html=html.substring(1);
}
}
}
public static void main(String[] args) {
getDefaulst();
getFirst();
getLast();
getDateTime(2);
}
}
//运行结果是:
默认情况下的结果:XXe
得到第一个的结果:XXb
得到最后一个的结果:XXe
得到第一个的时间是:2009-3-23 13:14:31
得到最后一个的时间是:2009-2-26 10:28:49
得到第 2 个的时间是:2009-3-23 13:12:54