正则表达

一、正则表达式介绍:

1、什么是正则表达式?

   符合一定(判断/校验)规则的表达式。

2、作用:专门用于处理字符串的。

3、好处:可以简化对字符串的复杂操作。

4、弊端:符号定义越多,正则越长,阅读性越差。

5、特点:用一些特定的符号来表示一些代码操作,这样就简化了书写。(所以学习正则表达式,就是在学习一些特殊符号的使用)

6、正则表达式的构造摘要:

构造

匹配

字符

x

字符x

\\

反斜线字符

\0n

带有八进制值 0 的字符 n (0 <= n <= 7)

\0nn

带有八进制值 0 的字符 nn (0 <= n <= 7)

\0mnn

带有八进制值 0 的字符 mnn(0 <= m <= 3、0 <= n <= 7)

\xhh

带有十六进制值 0x 的字符 hh

\uhhhh

带有十六进制值 0x 的字符 hhhh

\t

制表符 ('\u0009')

\n

新行(换行)符 ('\u000A')

\r

回车符 ('\u000D')

\f

换页符 ('\u000C')

\a

报警 (bell) 符 ('\u0007')

\e

转义符 ('\u001B')

\cx

对应于 x 的控制符

字符类

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

POSIX 字符类(仅 US-ASCII)

\p{Lower}

小写字母字符:[a-z]

\p{Upper}

大写字母字符:[A-Z]

\p{ASCII}

所有 ASCII:[\x00-\x7F]

\p{Alpha}

字母字符:[\p{Lower}\p{Upper}]

\p{Digit}

十进制数字:[0-9]

\p{Alnum}

字母数字字符:[\p{Alpha}\p{Digit}]

\p{Punct}

标点符号:!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

\p{Graph}

可见字符:[\p{Alnum}\p{Punct}]

\p{Print}

可打印字符:[\p{Graph}\x20]

\p{Blank}

空格或制表符:[ \t]

\p{Cntrl}

控制字符:[\x00-\x1F\x7F]

\p{XDigit}

十六进制数字:[0-9a-fA-F]

\p{Space}

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

java.lang.Character 类(简单的 java 字符类型)

\p{javaLowerCase}

等效于 java.lang.Character.isLowerCase()

\p{javaUpperCase}

等效于 java.lang.Character.isUpperCase()

\p{javaWhitespace}

等效于 java.lang.Character.isWhitespace()

\p{javaMirrored}

等效于 java.lang.Character.isMirrored()

Unicode 块和类别的类

\p{InGreek}

Greek块(简单块)中的字符

\p{Lu}

大写字母(简单类别

\p{Sc}

货币符号

\P{InGreek}

所有字符,Greek 块中的除外(否定)

[\p{L}&&[^\p{Lu}]]

所有字母,大写字母除外(减去)

边界匹配器

^

行的开头

$

行的结尾

\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

Reluctant 数量词

X??

X,一次或一次也没有

X*?

X,零次或多次

X+?

X,一次或多次

X{n}?

X,恰好 n

X{n,}?

X,至少 n

X{n,m}?

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

Possessive 数量词

X?+

X,一次或一次也没有

X*+

X,零次或多次

X++

X,一次或多次

X{n}+

X,恰好 n

X{n,}+

X,至少 n

X{n,m}+

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

Logical 运算符

XY

X 后跟 Y

X|Y

XY

(X)

X,作为捕获组

Back 引用

\n

任何匹配的 nth 捕获组

引用

\

Nothing,但是引用以下字符

\Q

Nothing,但是引用所有字符,直到 \E

\E

Nothing,但是结束从 \Q 开始的引用

特殊构造(非捕获)

(?:X)

X,作为非捕获组

(?idmsux-idmsux)

Nothing,但是将匹配标志idm s u x on - off

(?idmsux-idmsux:X)

X,作为带有给定标志 i d m s u x on - off

(?=X)

X,通过零宽度的正 lookahead

(?!X)

X,通过零宽度的负 lookahead

(?<=X)

X,通过零宽度的正 lookbehind

(?<!X)

X,通过零宽度的负 lookbehind

(?>X)

X,作为独立的非捕获组

 


二、正则表达式和字符串的集合应用:

①、匹配:boolean matches(String regex);用规则匹配整个字符串,只要有一处不符合规则,就匹配结束,返回false。

②、切割:String[] split(String regex);  通过规则来切割字符串,使用字符串数组接收。

③、替换:String replaceAll(String regex,String str); 如果regex中有定义组,可以在第二参数中通过$符号获取正则表达式中的已有的组。      

④、获取:将字符串中的符合规则的子串取出。

操作步骤:

     1) 将正则表达式封装成对象。

     2) 让正则对象和要操作的字符串相关联。

     3) 关联后,获取正则匹配引擎。

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

 

匹配:不使用正则表达式校验字符串的操作示例

/*

需求:对QQ号码进行校验。

要求:

①、位数:5~15

②、0不能开头

③、只能由数字组成。

 

第一种实现方式:判断语句 + String类中方法

*/

class RegexDemo
{
       public static void main(String[] args)
       {
              checkQQ();
       }
       public static void checkQQ()
       {
              String qq = "123a8845";    //定义输入的QQ号。
 
              int len = qq.length();   //定义变量用于表示QQ号的长度。
 
              if(len>=5 && len<=15)    //定义判断条件,用于判断QQ号的长度。
              {
                     if(!qq.startsWith("0"))   //判断QQ号是否是0开头。
                     {
                            char[] arr = qq.toCharArray(); 
                            boolean flag = true;
                            for(int x=0; x<arr.length; x++)
                            {
                                   if(!(arr[x]>='0' && arr[x]<='9'))  //判断QQ号是否都是由数字组成。
                                   {
                                          flag = false;
                                          break;
                                   }
                            }
                            if(flag)
                            {
                                   System.out.println("qq:"+qq);
                            }
                            else
                            {
                                   System.out.println("输入的QQ号出现非法字符");
                            }
                     }
                     else
                     {
                            System.out.println("QQ号不可以0开头");
                     }
              }
              else
              {
                     System.out.println("QQ号长度错误");
              }
       }
}


总结:以上方式使用了String类中的方法进行组合,虽然完成了需求,但是代码却过于复杂。

 

/*

第二种实现方式:正则表达式

*/

class Regex
{
       public static void main(String[] args)
       {
              checkQQ();
       }
       public static void checkQQ()
       {
              String qq = "1238845";  //定义输入的QQ号。
 
              String regex = "[1-9][0-9]{4,14}";   //定义QQ号校验规则。[1-9]表示第一个位置是1到9之间的数字,也就是开头不为0。[0-9]表示第二个位置是0到9之间的数字。{4,14}表示除了第一个位置的数字不为0之外,其它位置上都是0到9之间的数字。
 
              boolean flag = qq.matches(regex);   //使用String类中的matches方法去匹配校验规则,返回一个boolean类型的值,根据这个值的结果来判断输入的QQ号是否符合要求。
 
              if(flag)
                     System.out.println(qq+"...isok");
              else
                     System.out.println(qq+"......不合法");}
}

 

切割:使用正则表达式定义的规则来切割字符串

代码示例:

class RegexDemo
{
       public static void main(String[] args)
       {
              splitDemo("zhangsan.lisi.wangwu","\\.");    //使用一个点来切割。
              splitDemo("c:\\abc\\a.txt","\\\\");   //使用双斜杠来切割。
 
              splitDemo("erkktyqqquizzzzzo","(.)\\1+");   //按照叠词完成切割。
              //为了可以让规则结果被重用,可以将规则封装成一个组,用小括号()完成。
              //组的出现都有编号,从1开始。
              //想要使用已有的组,可以通过\n(n就是组的编号)的形式来获取。
 
              //((())())  这里是4个组。通过有多少个左括号就判断出有多少个组。从左往右数。
       }
       public static void splitDemo(String str,String reg)
       {
              String[] arr = str.split(reg);
              System.out.println(arr.length);
 
              for(String s : arr)
              {
                     System.out.println(s);
              }
       }
}


替换:使用指定的字符串替换匹配正则规则的字符串

代码示例:

class RegexDemo
{
       public static void main(String[] args)
       {
              String str = "wer1389980000ty1234564uiod234345675f";
              replaceAllDemo(str,"\\d{5,}","#");     //将字符串中的数字替换成#。
 
              Stringstr1 = "erkktyqqquizzzzzo";
              replaceAllDemo(str1,"(.)\\1+","&");      //将叠词替换成&
              replaceAllDemo(str1,"(.)\\1+","$1");    //将重叠的字符替换成单个字母。zzzz->z
       }
       public static void replaceAllDemo(String str,String reg,String newStr)
       {
              str = str.replaceAll(reg,newStr);
              System.out.println(str);
       }
}


获取:将字符串中的符合规则的子串取出。

代码示例:

import java.util.regex.*;
 
class RegexDemo2
{
       public static void main(String[] args)
       {
              getDemo();
       }
       public static void getDemo()
       {
              String str = "ming tian jiu yao fang jia le ,da jia";
              System.out.println(str);
              String reg = "\\b[a-z]{4}\\b";
 
              //1、将规则封装成对象。
              Pattern p = Pattern.compile(reg);
 
              //2、让正则对象和要作用的字符串相关联,通过matcher方法。
              //3、获取匹配器对象m
              Matcher m = p.matcher(str);
 
              //System.out.println(m.matches());  //其实String类中的matches方法。用的就是Pattern和Matcher对象来完成的。
              //只不过被String的方法封装后,用起来较为简单。但是功能却单一。
              //boolean b = m.find(); //将规则作用到字符串上,并进行符合规则的子串查找。
 
              while(m.find())
              {
                     System.out.println(m.group()); //通过循环,用于获取匹配后的结果。
                     System.out.println(m.start()+"...."+m.end());
              }
       }
}

 


***正则表达式演示——“网页爬虫”

需求:通过定义正则表达式程序获取指定文件或者网页中的邮箱地址。

 

import java.util.regex.*;
import java.io.*;
import java.net.*;
class RegexTest2
{
       public static void main(String[] args) throws Exception
       {
              getMails();
              getMails_1();
       }
 
       public static void getMails_1() throws Exception
       {
              //通过正则表达式匹配规则获取指定web页面上的邮箱地址。
              URL url = new URL("http://192.168.1.88: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());
                     }
              }
       }
}






  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值