正则

来源:互联网 发布:淘宝上买的车衣不耐用 编辑:程序博客网 时间:2024/04/26 04:01
注明出处:http://blog.csdn.net/lhy_ycu/article/details/45501777

前言


正则表达式可以说是用来处理字符串的一把利器,它是一个专门匹配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)

总结:一个字符用\,多个字符用[],字符次数用{} 


实例说明


(一)基本用法演示:

[java] view plain copy
  1. /** 
  2.  * 正则表达式实例演示说明 
  3.  *  
  4.  * @author [*昨日重现*] lhy_ycu@163.com 
  5.  * @since version 1.0 
  6.  * @datetime 2015年5月5日 下午2:27:50 
  7.  */  
  8.   
  9. public class RegexTest {  
  10.   
  11.     public static void main(String[] args) {  
  12.         // 单个字符  
  13.         System.out.println("a".matches("."));  
  14.         // 0~1个a  
  15.         System.out.println("a".matches("a?"));  
  16.         // 1~N个a  
  17.         System.out.println("aaaa".matches("a+"));  
  18.         // 0~N个a  
  19.         System.out.println("".matches("a*"));  
  20.         // 1~N个q和1个0~9之间的数字  
  21.         System.out.println("qqqqqq3".matches("q+[0-9]"));  
  22.         // 12~100个数字  
  23.         System.out.println("12345667890123".matches("\\d{12,100}"));  
  24.         // 0~3个数字分别以.分割  
  25.         System.out.println("192.168.0.1"  
  26.                 .matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"));  
  27.         // 第一个数字0~2,第二个数字0~9,第三个数字0~9  
  28.         System.out.println("192".matches("[0-2][0-9][0-9]"));  
  29.         // 4个任意空白  
  30.         System.out.println(" \n\r\t".matches("\\s{4}"));  
  31.         // 特殊字符\需转义  
  32.         System.out.println("\\".matches("\\\\"));  
  33.         // 以h开头,中间有0~N个字符,最后以o结尾  
  34.         System.out.println("hello".matches("^.*o$"));  
  35.         // 以h开头,中间1~3个字母尾随一个o,接着空白连着0~N个字符并以d结尾  
  36.         System.out.println("hello world".matches("^h[a-z]{1,3}o\\b.*d$"));  
  37.         // 以任意空白且不以换行开头为开头,并以换行结尾  
  38.         System.out.println("   \n".matches("^[\\s&&[^\\n]]*\\n$"));  
  39.         // 0~N个字符,连接4个数字和一个字符  
  40.         System.out.println("aaa 2222q".matches(".*\\d{4}."));  
  41.     }  
  42.   
  43. }  

(二)实际应用演示:

1、读取网页中所有的邮箱地址

[java] view plain copy
  1. /** 
  2.  * 读取某个网页中的所有邮箱地址--基本查找 
  3.  *  
  4.  * @author [*昨日重现*] lhy_ycu@163.com 
  5.  * @since version 1.0 
  6.  * @datetime 2015年5月5日 下午4:20:00 
  7.  */  
  8.   
  9. public class EmailTest {  
  10.   
  11.     public static void main(String[] args) {  
  12.         // 1~N个单词(可能含有.、-)连接 @1~N个单词连着 . 最后以com|org|cn|net其中之一结尾  
  13.         String emailTemplate = "[\\w[.-]]+@[\\w]+\\.(com|org|cn|net)";  
  14.         BufferedReader br = null;  
  15.         try {  
  16.             br = new BufferedReader(new InputStreamReader(new FileInputStream(  
  17.                     "d:\\email.html")));  
  18.             String line = null;  
  19.             StringBuffer sb = new StringBuffer();  
  20.             while ((line = br.readLine()) != null) {  
  21.                 sb.append(line).append("\n");  
  22.             }  
  23.             parse(sb.toString(), emailTemplate);  
  24.         } catch (FileNotFoundException e) {  
  25.             e.printStackTrace();  
  26.         } catch (IOException e) {  
  27.             e.printStackTrace();  
  28.         } finally {  
  29.             try {  
  30.                 br.close();  
  31.             } catch (Exception e2) {  
  32.                 // TODO: handle exception  
  33.                 e2.printStackTrace();  
  34.             }  
  35.         }  
  36.   
  37.     }  
  38.   
  39.     /** 
  40.      * 打印网页中的所有邮箱地址 
  41.      *  
  42.      * @param targetStr 
  43.      *            目标字符串 
  44.      * @param template 
  45.      *            待编译的正则模板 
  46.      */  
  47.     public static void parse(String targetStr, String template) {  
  48.         if (targetStr == null || template == null) {  
  49.             return;  
  50.         }  
  51.         // 获取编译好的待匹配的模板  
  52.         Pattern pattern = Pattern.compile(template);  
  53.         // 获取匹配目标字符串后产生的结果  
  54.         Matcher matcher = pattern.matcher(targetStr);  
  55.         // 若查找下一个匹配正则表达式的字符串  
  56.         while (matcher.find()) {  
  57.             // 则取出上一次与正则表达式匹配的字串。  
  58.             System.out.println("=======" + matcher.group());  
  59.         }  
  60.     }  
  61.   
  62. }  

2、代码行数统计:

[java] view plain copy
  1. /** 
  2.  * 代码统计:遍历某个项目的源文件的代码行数。 
  3.  *  
  4.  * 包括:空白行数、代码行数、注释行数。 
  5.  *  
  6.  * @author [*昨日重现*] lhy_ycu@163.com 
  7.  * @since version 1.0 
  8.  * @datetime 2015年5月5日 下午4:40:12 
  9.  */  
  10.   
  11. public class CodeCounter {  
  12.     /** 
  13.      * 空白行数 
  14.      */  
  15.     private static long whiteLines = 0;  
  16.     /** 
  17.      * 代码行数 
  18.      */  
  19.     private static long normalLines = 0;  
  20.     /** 
  21.      * 注释行数 
  22.      */  
  23.     private static long commentLines = 0;  
  24.   
  25.     public static void main(String[] args) {  
  26.          File srcDir = new File("D:\\workspace\\android\\Abc\\src");  
  27.         myList(srcDir);// 遍历所java源文件  
  28.         System.out.println("whiteLines = " + whiteLines);  
  29.         System.out.println("normalLines = " + normalLines);  
  30.         System.out.println("commentLines = " + commentLines);  
  31.         System.out.println("totalLines = " + getTotalLines());  
  32.     }  
  33.   
  34.     /** 
  35.      * 获取总行数 
  36.      */  
  37.     private static long getTotalLines() {  
  38.         long value = whiteLines + normalLines + commentLines;  
  39.         return value;  
  40.     }  
  41.   
  42.     /** 
  43.      * 遍历所java源文件 
  44.      */  
  45.     private static void myList(File srcDir) {  
  46.         System.out.println(srcDir + "目录下包含的目录和子文件有:");  
  47.         File[] files = srcDir.listFiles();  
  48.         for (File file : files) {  
  49.             System.out.println("----------" + file);  
  50.             if (file.getName().matches(".*\\.java$")) {  
  51.                 parse(file);  
  52.             }  
  53.             if (file.isDirectory()) {  
  54.                 myList(file);  
  55.             }  
  56.         }  
  57.     }  
  58.   
  59.     /** 
  60.      * 读取源文件内容 
  61.      *  
  62.      * @param file 
  63.      *            java文件 
  64.      */  
  65.     private static void parse(File file) {  
  66.         BufferedReader br = null;  
  67.         /** 
  68.          * 标识注释的开始或结束 
  69.          */  
  70.         boolean comment = false;  
  71.         try {  
  72.             br = new BufferedReader(new InputStreamReader(new FileInputStream(  
  73.                     file)));  
  74.             String line = null;  
  75.             while ((line = br.readLine()) != null) {  
  76.                 line = line.trim();  
  77.                 // 以任意空白且不以换行开头为开头,并以换行结尾  
  78.                 if (line.matches("^[\\s&&[^\\n]]*$")) {  
  79.                     whiteLines++;  
  80.                 } else if (line.startsWith("/*")) {  
  81.                     commentLines++;  
  82.                     comment = true;  
  83.                 } else if (comment == true) {  
  84.                     commentLines++;  
  85.                     if (line.endsWith("*/")) {  
  86.                         comment = false;  
  87.                     }  
  88.                 } else if (line.contains("//")) {  
  89.                     commentLines++;  
  90.                 } else {  
  91.                     normalLines++;  
  92.                 }  
  93.             }  
  94.         } catch (IOException e) {  
  95.             e.printStackTrace();  
  96.         } finally {  
  97.             if (br != null) {  
  98.                 try {  
  99.                     br.close();  
  100.                     br = null;  
  101.                 } catch (IOException e) {  
  102.                     e.printStackTrace();  
  103.                 }  
  104.             }  
  105.         }  
  106.     }  
  107. }  

(三)正则表达式进阶使用:

查找子串

[java] view plain copy
  1. String s1 = "123-45678-987-11";  
  2.         Pattern pattern = Pattern.compile("\\d{3,5}"); // 匹配3~5个数字  
  3.         Matcher matcher = pattern.matcher(s1);  
  4.         System.out.println(matcher.matches());// false  
  5.         matcher.reset();// 重置匹配器,将其添加位置设置为零  
  6.         System.out.println(matcher.find());// true,由于重置了匹配器此时将从起始位置查找  
  7.         System.out.println(matcher.start() + "-" + matcher.end());// 位置:0-3  
  8.         // 与matches方法唯一不同的是lookingAt不需要匹配整个区域 ,它永远是从第一个子串开始  
  9.         System.out.println(matcher.lookingAt());// true  
  10.         System.out.println(matcher.lookingAt());// true  

查找与替换

[java] view plain copy
  1. // CASE_INSENSITIVE:忽略子串大小写  
  2.         Pattern pattern2 = Pattern.compile("java", Pattern.CASE_INSENSITIVE);  
  3.         Matcher matcher2 = pattern2  
  4.                 .matcher("java Java JAVA jaVA jAVA ILoveYouJaVA youhateJaVa");  
  5.         // 将查找到的所有子串进行替换 (查找并替换)  
  6.         System.out.println(matcher2.replaceAll("JAVA"));  
原创粉丝点击