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