关闭

【黑马程序员】java中-------------正则表达式

366人阅读 评论(0) 收藏 举报
分类:

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

一. 正则表达式

1.     概念: 符合一定规律一定规则的表达式

2.     作用: 专门用里操作字符串的,用一些特定的符号集来表示一些代码操作,简化代码中的书写。

3.     弊端: 符号定义越多,正则越长,阅读性极差。

二. 正则表达式中常用的一些正则符号
            字符

构造                                  匹配

\\                                  反斜线字符

\t                                  制表符

\n                                  回车符

\f                                   换页符

          字符类

[abc]                             a、b或c(简单类)

[^abc]                           任何字符,除了a、b或c(否定)

[a-zA-Z]                          a到z或A到Z

[a-d[m-p]]                       a到d或m-p:[a-dm-p](并集)

[a-z&&[^bc]]                a到z,除了b和c

[a-z&&[^m-p]]              a到z,而非 m到p

        预定义字符类

                                  任何字符(与行结束符可能匹配也可能不匹配)

\d                                 数字: [0-9]

\D                                非数字:  |^[0-9]

\s                                空白字符:[ \t\n\x0B\f\r]

\S                                非空白字符:[^ \t\n\x0B\f\r]

\w                                单词字符:[a-zA-Z_0-9]

\W                                非单词字符:[^\w]

         边界匹配器

^                                行的开头

$                                行的结尾

\b                                单词边界

\B                                非单词边界

\A                                输入的开头

          Greedy数词量---->匹配整个字符串

X?                                X,一次或一次也没有

X*                                X,零次或多次

X+                                X,一次或多次

X{n}                             X,恰好n次

X{n,}                            X,至少n次

X{n,m}                        X,至少n次,但不超过m次

            组和捕获

捕获组可通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:

1    

((A)(B(C)))

2    

\A

3    

(B(C))

4    

(C)

组零始终代表整个表达式

          非捕获组

1.     (?:X)      X,作为非捕获组

2.     (?:x)

X,通过零宽度的正 lookahead

3.      (?!X)

X,通过零宽度的负 lookahead

4.      (?<=X)

X,通过零宽度的正 lookbehind

5.      (?<!X)

X,通过零宽度的负 lookbehind

6.      (?>X)

X,作为独立的非捕获组



三、正则用在替换操作

练习代码:

package Test;


public class ReplaceRegex
{
	public static void main(String[] args)
	{
		    //========替换======
		   System.out.println("=======替换=====");
		   //将数字,将数字替换成*
		   String strNum= "jian chi2010 jiu2011 shi2012 sheng 2014li";
		   replaceDemo(strNum,"*","\\d+");
		 
		   String strs = "eQQQQQQQQaaaaabbbbbbbc";
		  replaceDemo(strs, "$1","(.)\\1+");	//将两个或两个以上的相同字母替换成单个字母
		  
		  
		  replaceStr();
	}
	public static void replaceDemo(String str ,String newStr , String regex)
	{		
			
		
		   str = str.replaceAll(regex , newStr);
		  System.out.println(str);
	}
	
	
	public static void replaceStr()
	{
		String str = "我....要要要去北.....京一一一一一定.........要去北北北北北京坚..........持自己...做自己";
		/*
		将已有字符串变成另一个字符串。使用 替换功能。
		1,可以先将 . 去掉。
		2,在将多个重复的内容变成单个内容。
		*/
		
		str = str.replaceAll("\\.+", "");
		System.out.println(str);
		
		str = str.replaceAll("(.)\\1+", "$1");
		System.out.println(str);

	}
}

打印结果:

=======替换=====
jian chi* jiu* shi* sheng *li
eQabc
我要要要去北京一一一一一定要去北北北北北京坚持自己做自己
我要去北京一定要去北京坚持自己做自己


2、通过正则来对字符串进行切割操作

package Test;

public class RegexSplit {
    public static void main(String[] args)  
    {  
        // ========切割=======  
        String str1 = "java1 java2 java3 java4";  
        String str2 = "J.A.V.A";  
        System.out.println("切割str1的结果:");  
       
        //用逻辑或来连接,表示符合其中一个正则就可以  
        splitDemo1(str1," +|\\.");   //" +"表示一个或多个空格(X+),"\\."以点为分隔符号,  
        System.out.println("切割str2的结果:");  
      
        splitDemo1(str2," +|\\.");  
          
        ////按照连续出现2个以上重复的字符来切割,例如KK  
        String str3 = "abcQQdefOOOOast";  
        System.out.println("切割str3的结果:");  
        splitDemo1(str3 , "(.)\\1+");  
        
        
      
    }  
    //切割函数
    public static void splitDemo1(String str , String regex)  
    {  
          String[] arrs = str.split(regex);  
          System.out.println("长度为: "+ arrs.length);  
          for(String s : arrs)  
          {  
              System.out.println(s);  
          }  
    }  


}

打印结果:

切割str1的结果:
长度为: 4
java1
java2
java3
java4
切割str2的结果:
长度为: 4
J
A
V
A
切割str3的结果:
长度为: 3
abc
def
ast

3、通过正则规则,获取字符串中指定规则的子串

用的java中的Pattern和Matcher对象

其实,String中的matches()方法的底层就是用的这两个对象,只是将其封装了


代码练习:

package Test;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexGetMethod {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

        String str = "wwwwww abc holle efg yyyyy";  
       
        //“\\b”表示单词边界;[a-z]{3}表示字母a-z中出现3次的 
        getSub(str, "\\b[a-z]{3}\\b"); 
        
        
  
    }  
    //获取子串  
    public static void getSub(String str, String regex){  
        //将规则封装成对象  
        Pattern p = Pattern.compile(regex);  
        //让正则对象和要作用的字符集相关联,获取匹配器对象  
        Matcher m = p.matcher(str);  
        //boolean b = m.find();//将规则作用到字符串上,并进行符合规则的子串查找  
        //m.group();//用于获取匹配后结果  
        while(m.find()){  
            System.out.print(m.group());  
            System.out.println("-->位置为:" + m.start() + "---" + m.end());  
        }  
          
    }  
   
} 

打印结果:

abc-->位置为:7---10
efg-->位置为:17---20
4、通过正则对IP地址进行排序

练习代码:

package Test;

import java.util.Arrays;
import java.util.TreeSet;

public class SortIp {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ipSort();
		System.out.println("------------------------------");
		ipSort1();
		System.out.println("-------------------------------");
		//checkMail();
	}
	public static void ipSort()  
    {  
        String ip = "192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30";  
       
        ip = ip.replaceAll("(\\d+)", "00$1");  //表示0-9一次或多次的组替换成这个组加两个零
        System.out.println("补零后的ip:"+ip);  				//测试
          
        ip = ip.replaceAll("0*(\\d{3})", "$1");  
        System.out.println("替换成每段为3位数字的IP:"+ip);  
       
        String[] strs = ip.split(" ");  //安空格进行切割
        Arrays.sort(strs);  			//排序
        for(String str : strs){  
            str = str.replaceAll("0*(\\d+)", "$1");  
            System.out.println(str);  
        } 
    }
    public static  void ipSort1()  
    {     
        	String ip = "192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30";          
        		ip = ip.replaceAll("(\\d+)","00$1");  
                System.out.println("一次替换:"+ip);  
               
                ip = ip.replaceAll("0*(\\d{3})","$1");    
                System.out.println("二次替换:"+ip);  
               
                String[] arr = ip.split(" "); 
                
                //通过建立具有排序功能的集合进行自动排序
                TreeSet<String> ts = new TreeSet<String>();  
                for(String s : arr)       
                 {            
                    ts.add(s); //添加进集合
                    System.out.println("字符小串"+s);
                 }        
               for(String s : ts)     //遍历集合
              {           
                System.out.println(s.replaceAll("0*(\\d+)","$1"));    
              }     
     }  
    //匹配邮件地址:
    public static void checkMail()  
    {  
        String mail = "abc12@sina.com";  
        //mail = "1@1.1";  
          
        String reg = "[a-zA-Z_0-9]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,2}";//较为精确的匹配。  
        //reg = "\\w+@\\w+(\\.\\w+){1,2}";//相对不太精确的匹配。  
        //mail.indexOf("@")!=-1  
          
        System.out.println(mail.matches(reg));  
    }  
}

打印结果:

补零后的ip:00192.0068.001.00254 00102.0049.0023.00013 0010.0010.0010.0010 002.002.002.002 008.00109.0090.0030
替换成每段为3位数字的IP:192.068.001.254 102.049.023.013 010.010.010.010 002.002.002.002 008.109.090.030
2.2.2.2
8.109.90.30
10.10.10.10
102.49.23.13
192.68.1.254
------------------------------
一次替换:00192.0068.001.00254 00102.0049.0023.00013 0010.0010.0010.0010 002.002.002.002 008.00109.0090.0030
二次替换:192.068.001.254 102.049.023.013 010.010.010.010 002.002.002.002 008.109.090.030
字符小串192.068.001.254
字符小串102.049.023.013
字符小串010.010.010.010
字符小串002.002.002.002
字符小串008.109.090.030
2.2.2.2
8.109.90.30
10.10.10.10
102.49.23.13
192.68.1.254
-------------------------------

对网页爬虫,我是学习比别人的代码:


package Test;

/* 
网页爬虫(蜘蛛) 
*/  
import java.io.*;  
import java.util.regex.*;  
import java.net.*;  
import java.util.*;  
class RegexTest   
{  
	public static void main(String[] args) throws Exception  
	{  
		getMails_1();  
	}  
  
  //查找网页中的mail地址
	public static void getMails_1()throws Exception  
	{  
		URL url = new URL("http://192.168.1.254:8080/myweb/mail.html");  
  
		URLConnection conn = url.openConnection();  
  
		BufferedReader bufIn = new BufferedReader(new InputStreamReader(conn.getInputStream()));  
  
		String line = null;  
  
		String mailreg = "\\w+@\\w+(\\.\\w+)+";  
		Pattern p = Pattern.compile(mailreg);  
		while((line=bufIn.readLine())!=null)  
		{  
			Matcher m = p.matcher(line);  
			while(m.find())  
			{  
				System.out.println(m.group());  
			}  
		}  
	}  
  
	/* 
	获取指定文档中的邮件地址。 
	使用获取功能。Pattern Matcher 
	*/  
	public static void getMails()throws Exception  
	{  
		BufferedReader bufr =   
		new BufferedReader(new FileReader("mail.txt"));  
	  
		String line = null;  
	  
		String mailreg = "\\w+@\\w+(\\.\\w+)+";  
		Pattern p = Pattern.compile(mailreg);  
	  
  
  
		while((line=bufr.readLine())!=null)  
		{  
			Matcher m = p.matcher(line);  
			while(m.find())  
			{  
				System.out.println(m.group());  
			}  
		}  
	}  
}













---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:11422次
    • 积分:349
    • 等级:
    • 排名:千里之外
    • 原创:26篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档