------- android培训、java培训、期待与您交流! ----------
正则表达式
day28 01-正则表达式(概述)
1、正则表达式:正确的规则。它的体现,是表达式。
2、正则表达式用于操作字符串数据。
3、需求:定义一个功能对QQ号码进行校验。要求:长度5-15,只能是数字,0不能开头。
4、代码示例1——以前的写法
public static void checkQQ(String qq){
int len = qq.length();
if(len>=5&&len<=15){
if(!qq.startsWith("0")){
try{
long l =Long.parseLong(qq);
System.out.println(l+"正确");
}catch(NumberFormatExceptione){
System.out.println(qq+"含有非法字符");
}
}else{
System.out.println(qq+":不能0开头");
}
}else{
System.out.println(qq+":长度错误");
}
}
5、 但这么写也太麻烦了
6、java.lang
类String
boolean | matches(String regex) |
7、代码示例2——正则表达式写法
public static voidmain(String[] args) {
// TODOAuto-generated method stub
String regex = "[1-9][0-9]{4,14}";
String qq = "123456";
boolean b =qq.matches(regex);
System.out.println(qq+":"+b);
}
运行结果:123456:true
8、正则表达式用于操作字符串数据。通过一些特定的符号来体现。所以我们为了掌握正则表达式,必须要学习一些符号。虽然简化了,但是阅读性差。
day28 02-正则表达式(常见的规则)
1、java.util.regex包的Patten类中,有很多正则表达式的符号。
构造 | 匹配 |
| |
字符 | |
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] |
边界匹配器 | |
^ | 行的开头 |
$ | 行的结尾 |
\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 次 |
2、举个例子:
String str = "aoob";
String reg ="ao?b";//代表a与b之间,o出现了一次或多次。
System.out.println(str.matches(reg));
运行结果:false
如果str = "aob";结果就是true。str = "ab";结果也是true。
3、举个例子
String str = "aoooob";
String reg = "ao{4}b";
System.out.println(str.matches(reg));
运行结果:true
day28 03-正则表达式(常见的功能1-匹配)
1、正则表达式对字符串的常见操作1——匹配——String类的matches方法
boolean | matches(String regex) |
2、代码示例1——演示匹配
public classMatchesDemo {
public static voidmain(String[] args) {
//匹配手机号码是否正确
String tel = "15800001111";
String regex = "1[358][0-9]{9}";//可以简化为"1[358]\\d{9}"
boolean b =tel.matches(regex);
System.out.println(tel+":"+b);
}
}
运行结果:15800001111:true
3、可以简化为"1[358]\\d{9}",为啥此处要俩反斜线?
答:d是一个普通字符。\d是正则中的“数字[0-9]”。“\d”变成字符串了,变成字符串以后,反斜杠会自动对他后面那一个字符进行转义。d被转义了,d被转义完是什么?不知道。但我要的是反斜杠和d组合成的正确规则。所以,这反斜杠应该是普通符号。不能是转义字符。怎么办?再把这个反斜杠转义一下。“\\d”,哦了。
用第一个反斜杠把第二个反斜杠转义成普通反斜杠,再和d组合,就成了正则中的“数字”。
day28 04-正则表达式(常见的功能2-切割)
1、正则表达式对字符串的常见操作2——切割——String类的split方法。
String[] | |
String[] |
2、代码示例1——切割"zhangsan xiaoqiangzhaoliu"
public class SplitDemo1 {
public static void main(String[] args) {
String str = "zhangsan xiaoqiangzhaoliu";
String[] names = str.split(" ");
for(String name:names){
System.out.println(name);
}
}
}
运行结果:
zhangsan
xiaoqiang
zhaoliu
3、代码示例2——切割"zhangsan xiaoqiang zhaoliu"
public class SplitDemo2 {
public static void main(String[] args) {
String str = "zhangsan xiaoqiang zhaoliu";
String[] names = str.split(" +");
for(String name:names){
System.out.println(name);
}
}
}
运行结果:
zhangsan
xiaoqiang
zhaoliu
4、代码示例3——切割"zhangsan.xiaoqiang.zhaoliu"
这个你要是拿"."来切,就废了。"."在正则中是一个特殊符号,需要拿"\\."来切才可以。
public class SplitDemo3 {
public static void main(String[] args) {
String str = "zhangsan.xiaoqiang.zhaoliu";
String[] names = str.split("\\.");
for(String name:names){
System.out.println(name);
}
}
}
运行结果:
zhangsan
xiaoqiang
zhaoliu
5、代码示例4——切割"zhangsanttttxiaoqiangmmmmmmzhaoliu"
public class SplitDemo4 {
public static void main(String[] args) {
String str = "zhangsanttttxiaoqiangmmmmmmzhaoliu";
String[] names = str.split("(.)\\1+");
for(String name:names){
System.out.println(name);
}
}
}
运行结果:
zhangsan
xiaoqiang
zhaoliu
6、
7、正则表达式中,组的概念
Logical 运算符 | |
XY | X 后跟 Y |
X|Y | X 或 Y |
(X) | X,作为捕获组 |
8、((A)(B(C)))怎么编的组号?
方法:从左括号开始看,按着左括号来数这组。
第1组:((A)(B(C)))
第2组:(A)
第3组:(B(C))
第4组:(C)
0组:始终代表整个表达式。
day28 05-正则表达式(常见的功能3-替换)
1、正则表达式对字符串的常见操作3——替换——String类的replaceAll方法。
replaceAll | |
replaceFirst |
2、代码示例1——简单替换
public class ReplaceDemo1 {
public static void main(String[] args) {
String str = "zhangsanttttxiaoqiangmmmmmzhaoliu";
str = str.replaceAll("(.)\\1+", "#");//用#去替换重叠的符号
System.out.println(str);
}
}
运行结果:zhangsan#xiaoqiang#zhaoliu
3、代码示例2——把多个字母变成1个字母(把多个t变成1个t,把多个m变成1个m)
public class ReplaceDemo2 {
public static void main(String[] args) {
String str = "zhangsanttttxiaoqiangmmmmmzhaoliu";
str = str.replaceAll("(.)\\1+", "$1");//多个字母变成一个字母,前一个参数用了正则的话,“$1”代表拿前一个参数的第1组
System.out.println(str);
}
}
运行结果:zhangsantxiaoqiangmzhaoliu
4、代码示例3——电话号码隐藏15800001111 → 158****1111
public class ReplaceDemo3 {
public static void main(String[] args) {
String str = "15800001111";
str = str.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
System.out.println(str);
}
}
运行结果:158****1111
day28 06-正则表达式(常见的功能4-获取)
1、正则表达式对字符串的常见操作4——获取
(1)首先把正则规则封装成Pattern对象。
Pattern p =Pattern.compile("a*b");
(2)使用Pattern中的方法matcher方法与字符串相关联。获取要对字符串操作的匹配器对象Matcher。
(3)通过Matcher匹配器对象的方法对字符串进行操作。
boolean b = m.matcher();
2、相关的类与方法——Pattern
正则表达式的编译表示形式。
指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建 Matcher 对象,依照正则表达式,该对象可以与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式。
方法摘要 | |
| |
| |
| flags |
matcher | |
| matches |
pattern | |
| |
| split |
| split |
toString |
3、相关的类与方法——Matcher
方法摘要 | |
appendReplacement | |
appendTail | |
| end |
| end |
| find |
| find |
group | |
group | |
| groupCount |
| hasAnchoringBounds |
| hasTransparentBounds |
| hitEnd |
| lookingAt |
| matches |
pattern | |
| quoteReplacement |
region | |
| regionEnd |
| regionStart |
replaceAll | |
replaceFirst | |
| requireEnd |
reset | |
reset | |
| start |
| start |
toMatchResult | |
toString | |
useAnchoringBounds | |
usePattern | |
useTransparentBounds |
4、需求:获取由3个字母组成的单词。
5、代码示例
public class GetWord {
public static void main(String[] args) {
String str = "da jia hao , mingtian bu fang jia!";
String regex = "\\b[a-z]{3}\\b";//单词边界
//1、将正则封装成对象
Pattern p = Pattern.compile(regex);//Pattern没有对外的构造函数
//2、通过正则对象获取匹配器对象
Matcher m = p.matcher(str);
//使用Matcher对象的方法对字符串进行操作
//String类中的匹配、切割、替换,他们底层用的全是Pattern对象
//既然要获取三个字母组成的单词
//查找find()
System.out.println(str);
while(m.find()){//我调用一次find,他就那这规则对字符串进行查找
System.out.println(m.group());//获取匹配的子序列
System.out.println(m.start()+":"+m.end());
}
}
}
运行结果:
da jia hao , ming tian bu fang jia!
jia
3:6(包含3,但不包含6)
hao
7:10
jia
31:34
day28 07-正则表达式(练习_1)
1、练习1:治疗口吃:我我我我...我要...要要要...学学学...学学编...编编程...程程
2、代码示例:
publicclass Test_1 {
public static void main(String[] args) {
String str = "我我我我...我要...要要要...学学学...学学编...编编程...程程";
//1、将字符串中的"."去掉。用""替换
str = str.replaceAll("\\.+","");
System.out.println(str);
//2、替换叠词
str =str.replaceAll("(.)\\1+","$1");
System.out.println(str);
}
}
运行结果:
我我我我我要要要要学学学学学编编编程程程
我要学编程
day28 08-正则表达式(练习_2)
1、练习2:ip地址排序192.168.10.34、127.0.0.1、3.3.3.3、105.70.11.55
2、代码示例
public class Test_2 {
public static void main(String[] args) {
String ip_str = "192.168.10.34 127.0.0.1 3.3.3.3 105.70.11.55";
//1、为了让ip可以按照字符串顺序比较,只要让ip的每一段的位数相同。所以,补0.
//按照每一位所需,做多0进行补充,每一段都加上两个0
ip_str = ip_str.replaceAll("(\\d+)", "00$1");
System.out.println(ip_str);
//对于多了的0,每一段保留数字三位
ip_str = ip_str.replaceAll("0*(\\d{3})", "$1");
System.out.println(ip_str);
//这样之后我再切,再TreeSet,再排序
String[] ips = ip_str.split(" +");
TreeSet<String> ts = new TreeSet<String>();
for(String ip:ips){
ts.add(ip);
}
for(String ip:ts){
System.out.println(ip);
}
//对于多了的0进行替换
for(String ip:ts){
System.out.println(ip.replaceAll("0*(\\d+)","$1"));
}
}
}
运行结果:
00192.00168.0010.0034 00127.000.000.001 003.003.003.003 00105.0070.0011.0055
192.168.010.034 127.000.000.001 003.003.003.003 105.070.011.055
003.003.003.003
105.070.011.055
127.000.000.001
192.168.010.034
3.3.3.3
105.70.11.55
127.0.0.1
192.168.10.34
day28 10-正则表达式(练习_4)
1、练习4:网页爬虫,爬取邮箱地址
2、网页爬虫:在网页上寻找东西的爬虫。其实就是一个程序,用于在互联网上获取符合指定规则的数据。
3、代码示例:
class RegexTest2 {
public static void main(String[] args) throws IOException {
List<String> list =getMailsByWeb();
for(String mail : list){
System.out.println(mail);
}
}
public static List<String>getMailsByWeb() throws IOException {
//1,读取源文件。
// BufferedReader bufr = newBufferedReader(new FileReader("c:\\mail.html"));
URL url = new URL("http://192.168.1.100:8080/myweb/mail.html");
BufferedReader bufIn = new BufferedReader(newInputStreamReader(url.openStream()));
//2,对读取的数据进行规则的匹配。从中获取符合规则的数据.
String mail_regex = "\\w+@\\w+(\\.\\w+)+";
List<String> list = newArrayList<String>();
Pattern p = Pattern.compile(mail_regex);
String line = null;
while((line=bufIn.readLine())!=null){
Matcher m = p.matcher(line);
while(m.find()){
//3,将符合规则的数据存储到集合中。
list.add(m.group());
}
}
return list;
}
}