正则表达式

正则表达式

正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,模式描述在搜索文本时要匹配的一个或多个字符串。

正则表达式是一个强大的字符串处理工具,可以对字符串进行查找、提取、分割、替换等操作。

 

使用正则表达式对字符串进行操作的方法

Boolean matches(String regex):判断该字符串是否匹配指定的正则表达式。

String replaceAll(String regex,String replacement):将该字符串中所有匹配regex的子串替换为raplacement。

String replaceFirst(String regex,String replacement):将该字符串中第一个匹配regex的子串替换为raplacement。

String【】 split(String regex): 以regex为分割符,将该字符串分割成多个子串。

 

正则表达式是一个用于匹配字符串的模板。

正则表达式的特点是:

1. 灵活性、逻辑性和功能性非常强;
2. 可以迅速地用极简单的方式达到字符串的复杂控制。
3. 对于刚接触的人来说,比较晦涩难懂。
由于正则表达式主要应用对象是文本,因此它在各种文本编辑器场合都有应用,小到著名编辑器EditPlus,大到Microsoft Word、Visual Studio等大型编辑器,都可以使用正则表达式来处理文本内容。
 

要想真正的用好正则表达式,正确的理解元字符是最重要的事情。

   
   
   
   
   
   
   
   
   
   
   
   
合法字符 解释 特殊字符                                     说明
x 字符x(代表任何合法的字符) $ 匹配一行的结尾。要匹配$字符本身,使用\$
\0mnn 八进制数0mnn所代表的字符 ^ 匹配一行的开头。\^匹配^
\x 十六进制值0xhh所代表的字符 () 标记子表达式的开始和结束位置。\(和\)匹配(和)
\uhhhh 十六进制值0xhhh所代表的Unicode字符 [] 用于确定中括号表达式的开始和结束位置。\[和\]匹配[和]
\t 制表符(‘\u0009’) {} 用于标记前面子表达式的出现频度。\{和\} 匹配{和}
\n 新行(换行)符('\u000A') * 指定前面子表达式可以出现零次或多次。\*匹配 *
\r  回车符(‘\u000D’) + 指定前面子表达式可以出现一次或多次。\+ 匹配+
\f  换页符(‘\u000C’) ? 指定前面子表达式可以出现零次或一次。\?匹配?
\a 报警(bell)符(‘\u0007’)  . 匹配除换行符\n之外的任何单字符。\.
\e Eseape符('\u001B')  \ 用于转意下一个字符,或指定八进制,十六进制字符。\\
\cx x对应的控制符。如:\cM 匹配Ctrl-M。  |

指定两项之间任选一项。\|

Java字符串中反斜杠本身需要转意,因此两个反斜杠\\实际上相当于一个。

 

以上正则表达式只能匹配单个字符,而“通配符”是可以匹配多个字符的特殊字符,正则表达式中的“通配符”远超出了普通通配符的功能,又被称为预定义字符。

预定义字符                                         说明
. 可以匹配任何字符
\d 匹配数字0-9
\D 匹配非数字
\s 匹配所有的空白字符,包括制表符、空格、回车符、换页符、换行符
\S 匹配所有的非空白字符

\w
匹配所有的单词字符,包括数字,字母和下划线
\W 匹配所有的非单词字符

 

使用预定义字符创建正则表达式能匹配一批同种类型的字符串,如:c\\wt  能匹配cat、cbt、cct 等。

但是预定义字符串无法实现一些特殊情况的字符串匹配,如:匹配除ab之外的所有小写字母。

这时,方括号表达式就能派上用场了。

方括号表达式                                         说明
表示枚举 如:[abc],表示a,b,c中的任意字符
表示范围 - 如:[a-f],表示a~f范围内的任意字符
表示求否 ^ 如:[^abc] 表示非abc的任意字符
"与" && 如:[a-z&&[def]],a-z和[def]的交集,即d,e,f
“并” 并运算与前面的枚举类似。如:[a-d[m-p]]  即[a-dm-p]

 

 方括号表达式可以匹配所有的中文字符,中文字符的Unicode值是连续的,匹配形式为[\\u004-\\u0064]。

除方括号表达式以外,圆括号表达式,可用于将多个表达式组合成一个子表达式。

圆括号表达式                                       说明
或运算符: | 如:( ( public ) | (protected) | ( private ) )  用于匹配其中之一

 

正则表达式还支持边界匹配符

边界匹配符                      说明
^ 行的开头
$ 行的结尾
\b 单词的边界
\B 非单词的边界
\A 输入的开头
\G 前一个匹配的结尾
\Z 输入的结尾,仅用于最后的结束符
\z 输入的结尾

正则表达式提供数量标示符,有如下几种模式:

Greedy 贪婪模式 : 数量表示默认使用贪婪模式,除非另有表示。贪婪模式的表达式会一直匹配下去,直到无法匹配为止。

Reluctant  勉强模式 : 也是最小匹配模式,只会匹配最少的字符,用问号后缀表示‘?’。

Possessive  占用模式 : 用‘+’加号表示,比较少用。

贪婪模式 勉强模式 占用模式                               说明
X? X?? X?+ X表达式只出现零次或一次
X* X*? X*+ X表达式出现零次或多次
X+ X+? X++ X表达式出现一次或多次
X{n} X{n}? X{n}+ X表达式出现n次
X{n,} X{n,}? X{n,}+ X表达式最少出现n次
X{n.m} X{n,m}? X{n,m}+ X表达式最少出现n次,最多出现m次

贪婪模式和勉强模式的对比

 

String str = "hello , java!";
//replaceFirst()方法将字符串中第一个匹配的子串替换
System.out.println(str.replaceFirst("\\w*","¥")); //贪婪模式
System.out.println(str.replaceFirst("\\w*?","¥")); //勉强模式

 

使用正则表达式

定义正则表达式后,可以用 Pattern 和 Matcher 来使用正则表达式。

Pattern对象是正则表达式编译后在内存中的表示形式,因此,正则表达式字符串必须先被编译成Pattern对象,再利用该Pattern对象创建对应的Matcher对象。执行匹配所涉及的状态保留在 Matcher 对象中,多个Matcher 对象可共享同一个Pattern对象。

如:

Pattern p = Pattern.compile(a*b);    //编译Pattern对象
Matcher m = p.matcher("aaaaab"); //创建Matcher对象
boolean b = m.mathes();

Matcher 类提供的常用方法:

find(): 返回目标字符串中是否包含与Pattern匹配的子串

group(): 返回上一次与Pattern匹配的子串

start(): 返回上一次与Pattern匹配的子串在目标字符串中的开始位置

end(): 返回上一次与Pattern匹配的子串在目标字符串的结束位置加1

lookingAt():返回目标字符串前面部分与Pattern是否匹配

matches(): 返回整个目标字符串与Pattern是否匹配

reset(): 将现有的Matcher对象应用于一个新的字符序列

 

 CharSequence接口代表一个各种表示形式的字符串。

 

实例应用

 1,识别电话号码

通过Matcher类的find()和 group()方法可以从目标字符串中依次取出特定子串,如电话号码,其正则表达式为  ((13\\d)|(15\\d))\\d{8})k

获取以 13 或 15 开头的电话号码。

 


import java.util.regex.*;
public class FindGroup
{
 public static void main(String[] args)
 {
  String str = "我想求购一本《疯狂Java讲义》,尽快联系我13500006666"
  + "交朋友,电话号码是13611125565"
   + "出售二手电脑,联系方式15899903312";
  Matcher m = Pattern.compile("((13\\d)|(15\\d))\\d{8}")
   .matcher(str);
  // 将所有符合正则表达式的子串(电话号码)全部输出
  while(m.find())
  {
   System.out.println(m.group());
  }
 }

}


 

2,对目标字符串进行分割,查找,替换等操作 

 

import java.util.regex.*;
public class ReplaceTest
{
 public static void main(String[] args)
 {
  String[] msgs =
  {
   "Java has regular expressions in 1.4",
"regular expressions now expressing in Java",
   "Java represses oracular expressions"
  };
  Pattern p = Pattern.compile("re\\w*"); //编译Pattern对象
  Matcher matcher = null;
  for (int i = 0 ; i < msgs.length ; i++)
  {
   if (matcher == null)
   {
    matcher = p.matcher(msgs[i]); //创建matcher对象
   }
   else
   {
    matcher.reset(msgs[i]);
   }
   System.out.println(matcher.replaceAll("哈哈:)")); //把所有出现"re\\w*"的地方替换成 “哈哈:)”
  }
 }
}

 

 

posted @ 2018-04-27 13:26  Reyon  阅读(199)  评论(0编辑  收藏  举报