黑马程序员_java基础-正则表达式

来源:互联网 发布:运单软件合成 编辑:程序博客网 时间:2024/05/20 05:47

<a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流!

正则表达式

正则表达式的规则:

作用:用于专门操作字符串,学习正则表达式就是在学习一些特殊符号的使用.

特点:用于一些特定的符号来表示一些码操作.简化书写.

好处:可以简化对字符串的操作.

类 Pattern

指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建Matcher对象,依照正则表达式,该对象可以与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式。

因此,典型的调用顺序是:

Pattern p = Pattern.compile(“a*b”);

Matcher m = P.matcher(“aaaaaaa”);

Boolean b = m.matches();

在仅使用一次正则表达式时,可以方便的通过此类定义matches方法.此方法编译表达式并在单个调用中将输入序列与其匹配.语句:Boolean b = Pattern.matches(“a*b”,”aaaaaaa”);等效于上面的三行语句,尽管对于重复的匹配而言它的效率不高,因为它不允许重用已编译的模式.

     此类的实例是不可变的,可供多个并发线程安全使用.Matcher类的实例用于此目的则不安全

正则表达式的构造摘要:

字符类:

 

字符类

[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&&[def]]

d、e 或 f(交集)

[a-z&&[^bc]]

a 到 z,除了 b 和 c:[ad-z](减去)

[a-z&&[^m-p]]

a 到 z,而非 m 到 p:[a-lq-z](减去)

预定义字符类

.

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

\d

数字:[0-9]

\D

非数字: [^0-9]

\s

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

\S

非空白字符:[^\s]

\w

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

\W

非单词字符:[^\w]


边界匹配器

^

行的开头

$

行的结尾

\b

单词边界

\B

非单词边界

\A

输入的开头

\G

上一个匹配的结尾

\Z

输入的结尾,仅用于最后的结束符(如果有的话)

\z

输入的结尾

 

 

Greedy 数量词

X?

X,一次或一次也没有

X*

X,零次或多次

X+

X,一次或多次

X{n}

X,恰好 n

X{n,}

X,至少 n

X{n,m}

X,至少 n 次,但是不超过 m

 

正则表达式的一些练习:

public class MatchingTest2

{

     public static void checkQQ(String qq)

     {

         //正则6-13位的数字,并且第一位不能为0

         String regex = "[1-9][0-9]{4,11}";

 

         boolean flag = qq.matches(regex);

 

         if (flag)

              System.out.println("QQ:" + qq);

         else

              System.out.println("不是QQ号!");

     }

 

     // 判断一个位置上的字符是否在请允许之内

     public static void regex_1()

     {

         String str = "a";

        

         String regex = "[abc]";

 

         //字符串str必须为abc中的一个

         System.out.println("是否匹配:" + str.matches(regex));

     }

 

     public static void regex_2()

     {

         String str = "b2";

         // 第一位是字母,第二位有可能有,也有可能没有(数字)

         String regex = "[a-zA-Z]\\d?";// ?有且只有一次

         // 第一位是字母,后面要么没有,要么出现多次

         regex = "[a-zA-z]\\d*";// *有可能有,有可能出现多次

         // 第一位是数字非0开头,后面出现5-11次数字

         regex = "[1-9]\\d{5,11}";// {5,11}匹配前一项5-11

 

         System.out.println(str.matches(regex));

     }

 

     public static void main(String[] args)

     {

         // Scanner s = new Scanner(System.in);

         // System.out.println("输入QQ:");

         // checkQQ(s.next());

         //regex_1();

         regex_2();

     }

}

 

//替换

public class ReplaceTest

{

     public static void main(String[] args)

     {

         String str = "abcdefg23zzz32323000000.asdf22222g&kjh";//将字符串中的数字替换成#

        

         replaceAllDemo(str, "\\d{5,}", "#");//超过五个数字的就替换

         replaceAllDemo(str, "(.)\\1+", "@");//将叠词替换成@

         replaceAllDemo(str, "(.)\\1+", "$1");//将叠词字母替换成单个字符,$符号取出组,$是个特殊符号,$是在表达式外面去获取

     }

     //替换字符串

     public static void replaceAllDemo(String str, String reg,String newStr)

     {

         str = str.replaceAll(reg, newStr);//newStr代表要替换的字符串,reg代表正则表达式

         System.out.println(str);

     }

}

 

//分割

public class SplitTest

{

     public static void main(String[] args)

     {

         split();

     }

    

     public static void split()

     {

         String str = "string    str is   sdfsdf";

         str = "zhang.san.li.shi";

         str = "c:\\java\\adf\\txt.txt";

         str = "adddfdqqsdfkksdfsfrrk";//按照叠词进行切割

        

         String regex = " +"; //按照多空格切

         regex = " ";//按一个空格切,切出来的达不到我们的目标要求,会有很多空行,按上面的切就不会" +"

         regex = "\\.";

         regex = "\\\\";

         regex = "(.)\\1+";//利用组进行切割,组是用小括括起来的并自动编号,后面有两个以上叠词就用字符加号连接

        

         String[] arr = str.split(regex);

        

         for (String s : arr)

         {

              System.out.println(s);

         }

     }

}

importjava.util.regex.*;

 

/*

 * 将字符串中符合规则的子串取出

 * 步骤:

 * 1.将正则表达式封装成对象

 * 2.让正则表达式对象和要操作的字符串相关联

 * 3.关联后获取正则匹配引擎

 * 4.通过引擎对符合规则的子串进行操作,比如取出

 */

public class Get

{

     public static void main(String[] args)

     {

         get();

     }

 

     public static void get()

     {

         String str = "strr name hello world,haha hehe";

 

         String reg = "\\b[a-z]{4}\\b";//匹配四个字母,"\\b"单词边界

 

         // 将规则封装成对象

         Pattern p = Pattern.compile(reg);

 

         // 让正则对象和要作用的字符串相关联,获取匹配器对象

         Matcher m = p.matcher(str);

 

         // 将规则作用到字符串上并进行符合规则的子串查找

         // boolean b = m.find();

 

         /*

          * 同一个匹配器用的是同一个索引位,当下面的这段代码执行后,

          * while()里面的输出结果就会找不到字符串"strr",因为索引位置已经在"name"的"n"处,也就是查到索引号5的位置

          */

         System.out.println(m.matches());

 

         while (m.find())

         {

              System.out.println(m.group());

 

              // 包含头不包含尾start()和end()用在group()方法后.

              System.out.println(m.start() +"......" + m.end());

         }

     }

}

 

importjava.io.*;

importjava.util.regex.*;

/*

 * 从一个文本文档中查询邮件地址

 */

public class GetMail

{

     public static void main(String[] args)

     {

         getMail();

     }

 

     public static void getMail()

     {

         //创建缓冲,提高效率

         BufferedReader br = null;

        

         //编写简单邮件地址正则表达式

         String mailReg = "\\w+@\\w+(\\.\\w+)+";

 

         //将规则封闭成对象

         Pattern p = Pattern.compile(mailReg);

        

         try

         {

              br = new BufferedReader(new FileReader("email.txt"));

 

              String line = null;

             

              int count = 0;//计数

             

              while ((line = br.readLine()) !=null)

              {

                   //将正则和要作用的字符串相关联,获取匹配器对象

                   Matcher m = p.matcher(line);

                  

                   //循环查找要匹配的值,返回boolean值

                   while(m.find())

                   {

                       //进行输出

                       System.out.println(++count +":" + m.group());

                   }

              }

 

         }

         catch (FileNotFoundException e)

         {

              e.printStackTrace();

         }

         catch (IOException e)

         {

              e.printStackTrace();

         }

         finally

         {

              if (br !=null)

              {

                   try

                   {

                       br.close();//关闭缓冲

                   }

                   catch (IOException e)

                   {

                       e.printStackTrace();

                   }

              }

         }

     }

}

反斜线、转义和引用


反斜线字符 ('\') 用于引用转义构造,如上表所定义的,同时还用于引用其他将被解释为非转义构造的字符。因此,表达式 \\ 与单个反斜线匹配,而 \{ 与左括号匹配。

在不表示转义构造的任何字母字符前使用反斜线都是错误的;它们是为将来扩展正则表达式语言保留的。可以在非字母字符前使用反斜线,不管该字符是否非转义构造的一部分。

根据 Java Language Specification 的要求,Java 源代码的字符串中的反斜线被解释为 Unicode转义或其他字符转义。因此必须在字符串字面值中使用两个反斜线,表示正则表达式受到保护,不被 Java 字节码编译器解释。例如,当解释为正则表达式时,字符串字面值 "\b" 与单个退格字符匹配,而 "\\b" 与单词边界匹配。字符串字面值 "\(hello\)" 是非法的,将导致编译时错误;要与字符串(hello) 匹配,必须使用字符串字面值 "\\(hello\\)"。

字符类

字符类可以出现在其他字符类中,并且可以包含并集运算符(隐式)和交集运算符(&&)。并集运算符表示至少包含其某个操作数类中所有字符的类。交集运算符表示包含同时位于其两个操作数类中所有字符的类。

字符类运算符的优先级如下所示,按从最高到最低的顺序排列:

1

字面值转义

\x

2

分组

[...]

3

范围

a-z

4

并集

[a-e][i-u]

5

交集

[a-z&&[aeiou]]

注意,元字符的不同集合实际上位于字符类的内部,而非字符类的外部。例如,正则表达式. 在字符类内部就失去了其特殊意义,而表达式 - 变成了形成元字符的范围。