正则表达式的组成规则
规则字符在java.util.regex Pattern类中
A:字符
x 字符 x。举例:'a'表示字符a
\\ 反斜线字符。
\n 新行(换行)符 ('\u000A')
\r 回车符 ('\u000D')
B:字符类
[abc] a、b 或 c(简单类)
[^abc] 任何字符,除了 a、b 或 c(否定)
[a-zA-Z] a到 z 或 A到 Z,两头的字母包括在内(范围)
[0-9] 0到9的字符都包括
C:预定义字符类
. 任何字符。我的就是.字符本身,怎么表示呢? \.
\d 数字:[0-9]
\w 单词字符:[a-zA-Z_0-9]
在正则表达式里面组成单词的东西必须有这些东西组成
D:边界匹配器
^ 行的开头
$ 行的结尾
\b 单词边界
就是不是单词字符的地方。
举例:hello world?haha;xixi
E:Greedy 数量词
X? X,一次或一次也没有 比如""空串 就是没有
X* X,零次或多次 大于等于1次 都算多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过 m 次
public class MyTest {
public static void main(String[] args) {
//正则表达式:正确规则的表达式,一门独立的语法,很多语言都支持,作用用来定义一些规则,对数据进行校验。
//正则表达式的语法:
//Java中用字符串来定义正则
String regx = "b"; //用来匹配单个字符
regx = "[a,b,c,d,e,f,g]";//这个集合中所罗列的的任意一个字符
regx = "[a-z]";
regx = "[A,B,C]";
regx = "[A-Z]";
regx = "[0-9]";
regx = "[a-zA-Z0-9]";
regx = "[^a-z]"; //不是我罗列的某一个
regx = ".";//匹配单个任意字符
regx = "\\.";// \\ 转义字符 只匹配点本身
regx = "a|b"; // | 代表或者
regx = "\\|";//代表 竖线 转义
regx = "\\d"; // 跟[0-9] 意思一样
regx = "\\w";//跟 [a-zA-Z_0-9] 意思一样
regx = "a+b+"; //+代表一个或多个
regx = "[a-z]+";
regx = "a*"; //* 0次 或多次 一次也算多次
regx = "a?"; //一次或一次也不要出现
regx = "[a-zA-Z]{5}"; //正好几次
regx = "[0-9a-z]{5,}";//至少5次
regx = "[a-zA-Z]{5,15}";// 5<=次数<=15
/* 需求:校验qq号码.
1:要求必须是5 - 15 位数字
2:0 不能开头*/
String qqRegx = "[1-9][0-9]{4,14}";
System.out.println(b);
//手机正则:
String phoneRegx="[1][3,5,7,8,9][0-9]{9}";
}
}
正则表达式的判断功能
String类的功能:public boolean matches(String regex)
public class MyTest2 {
public static void main(String[] args) {
// 需求:校验邮箱:6~18个字符,可使用字母、数字、下划线,需以字母开头
//xibukaiyuan@163.com
//xibukaiyuan@163.
String regx="[a-zA-Z]\\w{5,17}@163\\.(com|net|cn|org)";
boolean matches = "xibukaiyuan@163.net".matches(regx);
System.out.println(matches);
//身份证正则
String id="[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]";
//车牌的正则
String car="[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}";
//中文的正则
String name="[\\u4e00-\\u9fa5]+";
boolean matches1 = "李四".matches(name);
System.out.println(matches1);
}
}
正则表达式的分割功能
String类的功能:public String[] split(String regex)
public class MyTest {
public static void main(String[] args) {
String str="我喜欢你=稀罕你=爱死你";
String str2 = "我喜欢你=稀罕你=爱死你=我喜欢你=稀罕你=爱死你";
// 根据正则来截取字符串
String[] strings = str2.split("=");
System.out.println(Arrays.toString(strings));
String str3 = "我喜欢你=asdfa稀罕你=asdfs1212爱死你=23232我喜欢你=212121稀罕你=asdfasdfefefefefeffefasdf爱死你";
String[] split = str3.split("[=a-z0-9]+");
System.out.println(Arrays.toString(split));
}
}
/*
需求:我有如下一个字符串:”91 27 46 38 50”,请写代码实现最终输出结果是:”27 38 46 50 91”
分析:
a: 定义目标字符串"91 27 46 38 50"
b: 对这个字符串进行切割,得到的就是一个字符串数组
c: 把b中的字符串数组转换成int类型的数组
(1): 定义一个int类型的数组,数组的长度就是字符串数组长度
(2): 遍历字符串数组,获取每一个元素.将其转换成int类型的数据
(3): 把int类型的数据添加到int类型的数组的指定位置
d: 排序
e: 创建一个StringBuilder对象,用来记录拼接的结果
f: 遍历int类型的数组, 将其每一个元素添加到StringBuilder对象中
g: 就是把StringBuilder转换成String
h: 输出
*/
import java.util.Arrays;
public class MyTest2 {
public static void main(String[] args) {
String str="91 27 46 38 50 21 11 1 121";
//经过你的改造后变成 ==> "27 38 46 50 91"
String[] arr = str.split(" +");
System.out.println(Arrays.toString(arr));
Arrays.sort(arr);
//字符串数组,是按照字典顺序排的
//System.out.println(Arrays.toString(split));
//定义一个int类型的数组
int[] ints = new int[arr.length];
//遍历字符串数组,取出每一个元素,放到int 数组中
for (int i = 0; i < arr.length; i++) {
ints[i]=Integer.parseInt(arr[i]);
}
//排序int数组
Arrays.sort(ints);
// System.out.println(Arrays.toString(ints));
//遍历int数组拼串
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ints.length; i++) {
sb.append(ints[i]).append(" ");
}
String string = sb.toString().trim();
System.out.println(string);
}
}
正则表达式的替换功能
String类的功能:public String replaceAll(String regex,String replacement)
public class MyTest {
public static void main(String[] args) {
//根据正则表达式来替换
String str="assdfasf11444444asdfasdfasfd asdfassdfasfd88799999asdfdasfasf55555555asdfasdfas888888asdfassdfasdfasdfdas asdfasdf";
//根据正则来替换
String s = str.replaceAll("[0-9 ]+", "");
System.out.println(s);
}
}
Pattern和Matcher的概述
正则的获取功能需要使用的类
模式和匹配器的典型调用顺序
通过JDK提供的API,查看Pattern类的说明
典型的调用顺序是
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();
Pattern
1.Pattern.pattern()
返回正则表达式的字符串形式
Pattern p=Pattern.compile("\\w+");
p.pattern();//返回 \w+
2.Pattern.split(CharSequence input)
该方法用于分割字符串,并返回一个String[].
Pattern p=Pattern.compile("\\d+");
String[] str=p.split("我的QQ是:456456我的电话是:0532214我的邮箱是:aaa@aaa.com");
运行结果:
str[0]=“我的QQ是:” str[1]=“我的电话是:” str[2]=“我的邮箱是:aaa@aaa.com”
3.Pattern.matchers(String regex,CharSequence input)
该方法是一个静态方法,用于快速匹配字符串,该方法将会匹配全部字符串
Pattern.matches("\\d+","2223");//返回true
Pattern.matches("\\d+","2223aa");//返回false,需要匹配到所有字符串才能返回true,这里aa不能匹配到
Pattern.matches("\\d+","22bb23");//返回false,需要匹配到所有字符串才能返回true,这里bb不能匹配到
Matcher
Matcher类提供三个匹配操作方法,三个方法均返回boolean类型,当匹配到时返回true,没匹配到则返回false。
1.Matcher.matches()
matches()方法匹配的是整个字符串
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("22bb23");
m.matches();//返回false,因为bb不能被\d+匹配,导致整个字符串匹配未成功.
Matcher m2=p.matcher("2223");
m2.matches();//返回true,因为\d+匹配到了整个字符串
2.Matcher.lookingAt()
lookingAt()对最前面的字符串进行匹配,只有匹配到的字符串在最前面才返回true.
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("22bb23");
m.lookingAt();//返回true,因为\d+匹配到了前面的22
Matcher m2=p.matcher("aa2223");
m2.lookingAt();//返回false,因为\d+不能匹配前面的aa
3.Matcher.find()
对指定的字符串进行匹配,匹配到的字符串可以在任意位置。
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("22bb23");
m.find();//返回true
Matcher m2=p.matcher("aa2223");
m2.find();//返回true
Matcher m3=p.matcher("aa2223bb");
m3.find();//返回true
Matcher m4=p.matcher("aabb");
m4.find();//返回false
4.Matcher.start()
返回匹配到的子字符串在字符串中的起始位置。
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("aaa2223bb");
m.find();//匹配2223
m.start();//返回3
5.Matcher.end()
返回匹配到的子字符串的最后一个字符的下一个索引值。注意!是下一个索引值,而不是该子字符串中最后一个字符的索引值!
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("aaa2223bb");
m.find();//匹配2223
m.end();//返回7,返回的是2223后的索引号
6.Matcher.group()
group即返回匹配到的字符串。
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("aaa2223bb");
m.find();//匹配2223
m.group();//返回2223
7.Matcher.start(int, i), Matcher.end(int, i), Matcher.group(int, i), Matcher.groupCount()
前三个API主要用于分组操作,取出第i组数据的索引值,groupCount()则用来返回一共匹配到多少组。
Pattern p=Pattern.compile("([a-z]+)(\\d+)"); //()表示分组,意义是括号内是一个整体
Matcher m=p.matcher("aaa2223bb");
m.find(); //匹配aaa2223
m.groupCount(); //返回2,因为有2组
m.start(1); //返回0 返回第一组匹配到的子字符串在字符串中的索引号
m.start(2); //返回3
m.end(1); //返回3 返回第一组匹配到的子字符串的最后一个字符在字符串中的索引位置.
m.end(2); //返回7
m.group(1); //返回aaa,返回第一组匹配到的子字符串
m.group(2); //返回2223,返回第二组匹配到的子字符串
案例
//使用正则表达式提取一段文本中的数字
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("我的QQ是:456456 我的电话是:0532214 我的邮箱是:aaa123@aaa.com");
while(m.find()) {
System.out.println(m.group());
}
运行结果:
456456
0532214
123
//如果将while循环替换成
while(m.find()) {
System.out.println(m.group());
System.out.print("start:"+m.start());
System.out.println(" end:"+m.end());
}
则输出:
456456
start:6 end:12
0532214
start:19 end:26
123
start:36 end:39
注意!只有当匹配成功后,才可以使用start(), end(), group()方法,否则会抛出java.lang.IllegalStateException。也就是说,当matchers(), lookingAt(), find() 其中一个方法返回true时,才可以使用start(),end(),group()方法。