黑马程序员--一十四、正则表达式
2014-01-13 21:50
211 查看
----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! -----------------------
定义:符合一定规则的表达式
作用:专门用于操作字符串
特点:用一些特定的符号来表示一些代码操作,这样就简化书写
好处:简化代码书写
弊端:符号定义越多,正则越长,阅读性越差。
常用符号:
注意:
1、组和捕获
捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:
1 ((A)(B(C)))
2 \A
3 (B(C))
4 (C)
组零始终代表整个表达式。
规则内获取组可用:\n(n表示组编号)
规则外获取组可用:$n(n表示组编号)
例:将叠字换成单个字符。如aaazzzbb——>azb
str = “aaazzzbb”
str.replaceAll(“(.)\\1+”, “$1”)
2、Greedy、Reluctant和Possessive数量词的区别:
举例如下:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternDemo {
public static void main(String[] args){
/*1.:Greedy(贪婪的)
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过 m 次
*/
Pattern p1 = Pattern.compile(".{3,10}[0-9]");
String s1 = "aaaa5bbbb6";
Matcher m1 = p1.matcher(s1);
if(m1.find())
System.out.println(m1.start() + "-" + m1.end());
else
System.out.println("not match!");
//输出:0-10
//解释:Greedy对这个表达式 {3,10}吞入最多字符(10个字符)把10个字符匹配。吞入的字符为:aaaa5bbbb6 吞入之后后面的[0-9]发现没有匹配的吐出最后一个字符看是数字结果匹配。
/*2:Reluctant(勉强的)
X?? X,一次或一次也没有
X*? X,零次或多次
X+? X,一次或多次
X{n}? X,恰好 n 次
X{n,}? X,至少 n 次
X{n,m}? X,至少 n 次,但是不超过 m 次
*/
Pattern p2 = Pattern.compile(".{3,10}?[0-9]");
String s2 = "aaaa5bbbb6";
Matcher m2 = p2.matcher(s2);
if(m2.find())
System.out.println(m2.start() + "-" + m2.end());
else
System.out.println("not match!");
//输出:0-5
//解释:Reluctant和Greedy相反对,这个表达式{3,10}的吞入最少字符(3个字符)把3个字符匹配。吞入的字符为:aaa 吞入之后后面的[0-9]发现没有匹配的吞入直到吞入5个字符匹配(aaaa5)。
/*
3:Possessive(独占的)
X?+ X,一次或一次也没有
X*+ X,零次或多次
X++ X,一次或多次
X{n}+ X,恰好 n 次
X{n,}+ X,至少 n 次
X{n,m}+ X,至少 n 次,但是不超过 m 次
*/
Pattern p3 = Pattern.compile(".{3,10}+[0-9]");
String s3 = "aaaa5bbbb6";
Matcher m3 = p3.matcher(s3);
if(m3.find())
System.out.println(m3.start() + "-" + m3.end());
else
System.out.println("not match!");
//输出:not match!
//解释:Possessive和Greedy类似的{3,10}的吞入最多字符(10个字符)把10个字符匹配。但是没发现匹配以上正则表达式,和Greedy区别就是不吐了。所以返回not match!
//可以看出Possessive效率比其他的用法要高,但是不常用。
}
}
matches(String regex)
2、替换
replaceAll(String regex, String replacement)
3、切割
split(String regex)
4、获取
步骤:
1)、将正则表达式封装成对象
Pattern p = Pattern.compile(reg);
2)、让正则表达式和要操作的字符串相关联,获取匹配器对象
Matcher m = p.matcher(str);
3)、通过引擎对符合规则的字符串进行操作。比如:取出。
m.find(),m.group()等等方法
Tips:
1、如果只想知道该字符是否对错,用匹配。
2、如果想将已有字符串变成另一个字符串,用替换。
3、如股票想按照自己的方式将字符串变成多个字符串,用切割。获取规则以外的字串。
4、想要拿到符合要求的字符串字串,用获取。获取符合规则的字串。
/*
* 将下列字符串转换成:我要学编程
* 我我...我我...我要..要...要要要....要学学...编..编编程..程程...
*
* 思路:
* 1、去掉 ... 符号
* 2、去掉重复字符
*/
public class RegexReduplication {
public static void main(String[] args)
{
String str = "我我...我我...我要..要...要要要....要学学...编..编编程..程程...";
str = str.replaceAll("\\.+","");
str = str.replaceAll("(.)\\1+","$1");
System.out.println(str);
}
}
2、IP地址排序
import java.util.Arrays;
/*
* 将ip地址进行地址段顺序的排序
* 192.68.1.254 , 102.49.23.013 , 10.10.10.10 , 2.2.2.2 , 8.109.90.30
*
* 思路:
* 1、将所有IP字段前添加00字符
* 2、将所有IP字段只保留三位.
* 3、切成数组,并自然排序
* 4、替换为原IP字段,打印到控制台
*/
public class RegexIPSort {
public static void main(String[] args)
{
String ip = "192.68.1.254 102.49.23.13 10.10.10.10 2.2.2.2 8.109.90.30";
ip = ip.replaceAll("(\\d+)","00$1");
ip = ip.replaceAll("0*(\\d{3})", "$1");
String[] ipStr = ip.split(" ");
Arrays.sort(ipStr);
for(String s : ipStr)
{
System.out.println(s.replaceAll("0*(\\d+)", "$1"));
}
}
}
3、网页爬虫
import java.io.*;
import java.util.regex.*;
public class RegexSpider {
public static void main(String[] args) throws Exception
{
BufferedReader br = new BufferedReader(
new FileReader("网页爬虫.txt"));
String line = null;
while((line = br.readLine()) != null)
{
Pattern p = Pattern.compile("\\w+@\\w+.(com|cn)");
Matcher m = p.matcher(line);
while(m.find())
{
System.out.println(m.group());
}
}
}
}
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! -----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! -----------------------
正则表达式:
符合一定规则的表达式。定义:符合一定规则的表达式
作用:专门用于操作字符串
特点:用一些特定的符号来表示一些代码操作,这样就简化书写
好处:简化代码书写
弊端:符号定义越多,正则越长,阅读性越差。
常用符号:
构 造 | 匹 配 |
字符及字符类 | |
\\ | 反斜线字符 |
\t | 制表符 |
\n | 换行符 |
\r | 回车符 |
\e | 转义符 |
[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(交集) |
. | 任何字符 |
\d | 数字[0-9] |
\D | 非数字 |
\s | 空白字符:[\t\n\x0B\f\r] |
\S | 非空白字符 |
\w | 单词字符:[ a-zA-Z_0-9] |
\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次 |
Reluctant(勉强的)数量词 | |
Greedy数量词后加 ? 符号 | |
Possessive(独占的)数量词 | |
Greedy数量词后加 + 符号 | |
Logical运算符 | |
XY | X后跟Y |
X | Y | X或Y |
(X) | X,作为捕获组 |
1、组和捕获
捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:
1 ((A)(B(C)))
2 \A
3 (B(C))
4 (C)
组零始终代表整个表达式。
规则内获取组可用:\n(n表示组编号)
规则外获取组可用:$n(n表示组编号)
例:将叠字换成单个字符。如aaazzzbb——>azb
str = “aaazzzbb”
str.replaceAll(“(.)\\1+”, “$1”)
2、Greedy、Reluctant和Possessive数量词的区别:
举例如下:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternDemo {
public static void main(String[] args){
/*1.:Greedy(贪婪的)
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过 m 次
*/
Pattern p1 = Pattern.compile(".{3,10}[0-9]");
String s1 = "aaaa5bbbb6";
Matcher m1 = p1.matcher(s1);
if(m1.find())
System.out.println(m1.start() + "-" + m1.end());
else
System.out.println("not match!");
//输出:0-10
//解释:Greedy对这个表达式 {3,10}吞入最多字符(10个字符)把10个字符匹配。吞入的字符为:aaaa5bbbb6 吞入之后后面的[0-9]发现没有匹配的吐出最后一个字符看是数字结果匹配。
/*2:Reluctant(勉强的)
X?? X,一次或一次也没有
X*? X,零次或多次
X+? X,一次或多次
X{n}? X,恰好 n 次
X{n,}? X,至少 n 次
X{n,m}? X,至少 n 次,但是不超过 m 次
*/
Pattern p2 = Pattern.compile(".{3,10}?[0-9]");
String s2 = "aaaa5bbbb6";
Matcher m2 = p2.matcher(s2);
if(m2.find())
System.out.println(m2.start() + "-" + m2.end());
else
System.out.println("not match!");
//输出:0-5
//解释:Reluctant和Greedy相反对,这个表达式{3,10}的吞入最少字符(3个字符)把3个字符匹配。吞入的字符为:aaa 吞入之后后面的[0-9]发现没有匹配的吞入直到吞入5个字符匹配(aaaa5)。
/*
3:Possessive(独占的)
X?+ X,一次或一次也没有
X*+ X,零次或多次
X++ X,一次或多次
X{n}+ X,恰好 n 次
X{n,}+ X,至少 n 次
X{n,m}+ X,至少 n 次,但是不超过 m 次
*/
Pattern p3 = Pattern.compile(".{3,10}+[0-9]");
String s3 = "aaaa5bbbb6";
Matcher m3 = p3.matcher(s3);
if(m3.find())
System.out.println(m3.start() + "-" + m3.end());
else
System.out.println("not match!");
//输出:not match!
//解释:Possessive和Greedy类似的{3,10}的吞入最多字符(10个字符)把10个字符匹配。但是没发现匹配以上正则表达式,和Greedy区别就是不吐了。所以返回not match!
//可以看出Possessive效率比其他的用法要高,但是不常用。
}
}
二、正则表达式常用方法
1、匹配matches(String regex)
2、替换
replaceAll(String regex, String replacement)
3、切割
split(String regex)
4、获取
步骤:
1)、将正则表达式封装成对象
Pattern p = Pattern.compile(reg);
2)、让正则表达式和要操作的字符串相关联,获取匹配器对象
Matcher m = p.matcher(str);
3)、通过引擎对符合规则的字符串进行操作。比如:取出。
m.find(),m.group()等等方法
Tips:
1、如果只想知道该字符是否对错,用匹配。
2、如果想将已有字符串变成另一个字符串,用替换。
3、如股票想按照自己的方式将字符串变成多个字符串,用切割。获取规则以外的字串。
4、想要拿到符合要求的字符串字串,用获取。获取符合规则的字串。
三、练习
1、去叠词/*
* 将下列字符串转换成:我要学编程
* 我我...我我...我要..要...要要要....要学学...编..编编程..程程...
*
* 思路:
* 1、去掉 ... 符号
* 2、去掉重复字符
*/
public class RegexReduplication {
public static void main(String[] args)
{
String str = "我我...我我...我要..要...要要要....要学学...编..编编程..程程...";
str = str.replaceAll("\\.+","");
str = str.replaceAll("(.)\\1+","$1");
System.out.println(str);
}
}
2、IP地址排序
import java.util.Arrays;
/*
* 将ip地址进行地址段顺序的排序
* 192.68.1.254 , 102.49.23.013 , 10.10.10.10 , 2.2.2.2 , 8.109.90.30
*
* 思路:
* 1、将所有IP字段前添加00字符
* 2、将所有IP字段只保留三位.
* 3、切成数组,并自然排序
* 4、替换为原IP字段,打印到控制台
*/
public class RegexIPSort {
public static void main(String[] args)
{
String ip = "192.68.1.254 102.49.23.13 10.10.10.10 2.2.2.2 8.109.90.30";
ip = ip.replaceAll("(\\d+)","00$1");
ip = ip.replaceAll("0*(\\d{3})", "$1");
String[] ipStr = ip.split(" ");
Arrays.sort(ipStr);
for(String s : ipStr)
{
System.out.println(s.replaceAll("0*(\\d+)", "$1"));
}
}
}
3、网页爬虫
import java.io.*;
import java.util.regex.*;
public class RegexSpider {
public static void main(String[] args) throws Exception
{
BufferedReader br = new BufferedReader(
new FileReader("网页爬虫.txt"));
String line = null;
while((line = br.readLine()) != null)
{
Pattern p = Pattern.compile("\\w+@\\w+.(com|cn)");
Matcher m = p.matcher(line);
while(m.find())
{
System.out.println(m.group());
}
}
}
}
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! -----------------------
相关文章推荐
- 程序员编程艺术3:寻找最小的k个数
- 今日面试问题总结
- 黑马程序员_JAVA基础——多态
- 程序员编程艺术_第一章左旋转字符串_C实现
- 黑马程序员--十三、类加载器和动态代理
- 黑马程序员高级学习视频IO输入输出流 将一个指定目录下的java文件的绝对路径,存储到一个文本文件中
- 做程序员有前途
- 面试问题
- 黑马程序员 Java高新技术五
- 黑马程序员_Java基础_02
- 黑马程序员_11_String类的常用方法
- iOS 面试题
- 合格java程序员需要的知识
- 黑马程序员-学习日志-文件的分割与合并
- 黑马程序员-学习日志-文件的合并
- 黑马程序员_JAVA基础——接口
- 程序员教你如何用代码创建一个 女朋友
- 程序员面试题精选100题(29)-调整数组顺序使奇数位于偶数前面[算法]
- 最新前端开发面试题
- 程序员是怎样练成的?