正则表达式可以说是用来处理字符串的一把利器,它是一个专门匹配n个字符串的字符串模板,本质是查找和替换。在实例演示之前先了解一下Pattern、Matcher这两个工具类,Pattern:编译好的带匹配的模板(如:Pattern.compile("[a-z]{2}");/ / 取2个小写字母);Matcher:匹配目标字符串后产生的结果(如:pattern.matcher("目标字符串");)。字符串还有一个自带的matches方法用来判断目标字符串是否匹配给定的正则表达式,格式为:targetStr.matches(regex); 返回类型为boolean。
. -可以匹配任意字符
\s -代表一个任意空白(空格、Tab)。
\S -代表一个任意的非空白。
\d -代表一个任意的数字(digital)。
\D -代表一个任意的非数字。
\w -代表一个单词字符。
-W -代表一个任意的非单词字符
注意:对于特殊字符,实际使用时记住要转义\ ,如:( ) [ ] { } \ ? * + ^(一行的开头) $(一行的结尾)|
? --代表它前面的东西可以出现0~1次
* --代表它前面的东西可以出现0~N次
+ --代表它前面的东西可以出现1~N次
{n,m} --代表它前面的东西可以出现n~m次
{n,} --代表它前面的东西至少出现n次
{,m} --代表它前面的东西最多出现m次
{n} --代表它前面的东西必须出现n次
枚举:[ab1] --代表a或b或者1。
范围:[a-c] --代表a,b,c中的任意一个字符。
枚举与范围:[a-c1-3]--代表a,b,c,1,2,3中的任意一个字符。
表示求否:[^a-c] --代表不含a,b,c其中任意一个字符。
表示求交:[a-g&&[^b-d]]:--代表a,e,f,g中的任意一个字符。
表示必须含有其中之一:(com|org|cn)
总结:一个字符用\,多个字符用[],字符次数用{}
(一)基本用法演示:
/**
* 正则表达式实例演示说明
*
* @author [*昨日重现*] [email protected]
* @since version 1.0
* @datetime 2015年5月5日 下午2:27:50
*/
public class RegexTest {
public static void main(String[] args) {
// 单个字符
System.out.println("a".matches("."));
// 0~1个a
System.out.println("a".matches("a?"));
// 1~N个a
System.out.println("aaaa".matches("a+"));
// 0~N个a
System.out.println("".matches("a*"));
// 1~N个q和1个0~9之间的数字
System.out.println("qqqqqq3".matches("q+[0-9]"));
// 12~100个数字
System.out.println("12345667890123".matches("\\d{12,100}"));
// 0~3个数字分别以.分割
System.out.println("192.168.0.1"
.matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"));
// 第一个数字0~2,第二个数字0~9,第三个数字0~9
System.out.println("192".matches("[0-2][0-9][0-9]"));
// 4个任意空白
System.out.println(" \n\r\t".matches("\\s{4}"));
// 特殊字符\需转义
System.out.println("\\".matches("\\\\"));
// 以h开头,中间有0~N个字符,最后以o结尾
System.out.println("hello".matches("^.*o$"));
// 以h开头,中间1~3个字母尾随一个o,接着空白连着0~N个字符并以d结尾
System.out.println("hello world".matches("^h[a-z]{1,3}o\\b.*d$"));
// 以任意空白且不以换行开头为开头,并以换行结尾
System.out.println(" \n".matches("^[\\s&&[^\\n]]*\\n$"));
// 0~N个字符,连接4个数字和一个字符
System.out.println("aaa 2222q".matches(".*\\d{4}."));
}
}
1、读取网页中所有的邮箱地址
/**
* 读取某个网页中的所有邮箱地址--基本查找
*
* @author [*昨日重现*] [email protected]
* @since version 1.0
* @datetime 2015年5月5日 下午4:20:00
*/
public class EmailTest {
public static void main(String[] args) {
// 1~N个单词(可能含有.、-)连接 @1~N个单词连着 . 最后以com|org|cn|net其中之一结尾
String emailTemplate = "[\\w[.-]]+@[\\w]+\\.(com|org|cn|net)";
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(
"d:\\email.html")));
String line = null;
StringBuffer sb = new StringBuffer();
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
parse(sb.toString(), emailTemplate);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
}
/**
* 打印网页中的所有邮箱地址
*
* @param targetStr
* 目标字符串
* @param template
* 待编译的正则模板
*/
public static void parse(String targetStr, String template) {
if (targetStr == null || template == null) {
return;
}
// 获取编译好的待匹配的模板
Pattern pattern = Pattern.compile(template);
// 获取匹配目标字符串后产生的结果
Matcher matcher = pattern.matcher(targetStr);
// 若查找下一个匹配正则表达式的字符串
while (matcher.find()) {
// 则取出上一次与正则表达式匹配的字串。
System.out.println("=======" + matcher.group());
}
}
}
/**
* 代码统计:遍历某个项目的源文件的代码行数。
*
* 包括:空白行数、代码行数、注释行数。
*
* @author [*昨日重现*] [email protected]
* @since version 1.0
* @datetime 2015年5月5日 下午4:40:12
*/
public class CodeCounter {
/**
* 空白行数
*/
private static long whiteLines = 0;
/**
* 代码行数
*/
private static long normalLines = 0;
/**
* 注释行数
*/
private static long commentLines = 0;
public static void main(String[] args) {
File srcDir = new File("D:\\workspace\\android\\Abc\\src");
myList(srcDir);// 遍历所java源文件
System.out.println("whiteLines = " + whiteLines);
System.out.println("normalLines = " + normalLines);
System.out.println("commentLines = " + commentLines);
System.out.println("totalLines = " + getTotalLines());
}
/**
* 获取总行数
*/
private static long getTotalLines() {
long value = whiteLines + normalLines + commentLines;
return value;
}
/**
* 遍历所java源文件
*/
private static void myList(File srcDir) {
System.out.println(srcDir + "目录下包含的目录和子文件有:");
File[] files = srcDir.listFiles();
for (File file : files) {
System.out.println("----------" + file);
if (file.getName().matches(".*\\.java$")) {
parse(file);
}
if (file.isDirectory()) {
myList(file);
}
}
}
/**
* 读取源文件内容
*
* @param file
* java文件
*/
private static void parse(File file) {
BufferedReader br = null;
/**
* 标识注释的开始或结束
*/
boolean comment = false;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(
file)));
String line = null;
while ((line = br.readLine()) != null) {
line = line.trim();
// 以任意空白且不以换行开头为开头,并以换行结尾
if (line.matches("^[\\s&&[^\\n]]*$")) {
whiteLines++;
} else if (line.startsWith("/*")) {
commentLines++;
comment = true;
} else if (comment == true) {
commentLines++;
if (line.endsWith("*/")) {
comment = false;
}
} else if (line.contains("//")) {
commentLines++;
} else {
normalLines++;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
br = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
查找子串
String s1 = "123-45678-987-11";
Pattern pattern = Pattern.compile("\\d{3,5}"); // 匹配3~5个数字
Matcher matcher = pattern.matcher(s1);
System.out.println(matcher.matches());// false
matcher.reset();// 重置匹配器,将其添加位置设置为零
System.out.println(matcher.find());// true,由于重置了匹配器此时将从起始位置查找
System.out.println(matcher.start() + "-" + matcher.end());// 位置:0-3
// 与matches方法唯一不同的是lookingAt不需要匹配整个区域 ,它永远是从第一个子串开始
System.out.println(matcher.lookingAt());// true
System.out.println(matcher.lookingAt());// true
// CASE_INSENSITIVE:忽略子串大小写
Pattern pattern2 = Pattern.compile("java", Pattern.CASE_INSENSITIVE);
Matcher matcher2 = pattern2
.matcher("java Java JAVA jaVA jAVA ILoveYouJaVA youhateJaVa");
// 将查找到的所有子串进行替换 (查找并替换)
System.out.println(matcher2.replaceAll("JAVA"));