黑马程序员__正则表达式
2013-03-09 09:42
232 查看
--------- android培训、java培训、期待与您交流!
------------
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
给定一个正则表达式和另一个字符串,我们可以达到如下的目的:
给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”);
可以通过正则表达式,从字符串中获取我们想要的特定部分。
正则表达式的特点是:
1. 灵活性、逻辑性和功能性非常的强;
2. 可以迅速地用极简单的方式达到字符串的复杂控制。
3. 对于刚接触的人来说,比较晦涩难懂。
正则表达式很好用,能够很好的把一些复杂的代码进行简化
比如下面的代码
publicclass RegexDemo {
publicstaticvoid main(String[] args) {
checkQQ();
checkQQ_1();
}
//用正则表达式判断是否与要求匹配
publicstaticvoid checkQQ(){
String qq =
"324203";
String regex =
"[1-9]\\d{4,14}";
boolean flag = qq.matches(regex);
if(flag){
System.out.println(qq+"...is ok");
}
else{
System.out.println(qq+".....非法");
}
}
//自己用语句判断字符串是否与要求匹配
publicstaticvoid checkQQ_1(){
String qq =
"1aaaaaa1";
int len = qq.length();
//判断一个QQ字符串是不是由首位不是0,长度为6-15位的由数字组成的字符串
//先判断长度对不对
if(len>=5 && len<=15){
//判断首位是不是0
if(!qq.startsWith("0")){
char[] arr = qq.toCharArray();
boolean flag =true;
//判断是不是全由数字组成
for(int x = 0;x<arr.length;
x++){
if(!(arr[x]>='0' && arr[x]<='9')){
flag =
false;
break;
}
}
if(flag){
System.out.println("qq:" + qq);
}
else{
System.out.println("出现非法字符");
}
}
else{
System.out.println("不可以0开头");
}
}
else{
System.out.println("长度错误");
}
}
}
由这段代码可以看出正则表达式要比自己去写判断语句简单很多
Sting类里有一些方法
下面说说正则表达式的规则
由文档可以知道Pattern没有构造函数摘要
所以Pattern肯定提供了获取本类对象的方法compile
那怎么定义正则表达式Regex呢
可以对单个字符匹配,也可以对多个字符匹配
如reg = “a[a-zA-Z]”表示有两个字符,第一个是a第二个为字母
reg = “[a-zA-Z][a-zA-Z0-9]+”表示第一个为字母,后面为一个或多个字母或数字
reg = “[a-zA-Z_][a-z]{3}”表示第一个为字母,后面有三个小写字母
reg = “[a-zA-Z_][a-z]{3,}”表示第一个为字母,后面至少有三个小写字母
reg = “[a-zA-Z_][a-z]{3,6}”表示第一个为字母,后面至少有三个小写字母最多有6个字母
还有很多的东西,到API文档里看比较详细
说几个比较特殊的
“.”是任意字符,所以要想用它只能写成\\.$为组的引用
再说说关于组的概念
reg = "(.)\\1+"为了可以让规则的结果被重用,可以将规则封闭成一个组,用()完成,组的出现都有编号,从1开始,想要使用已有的组可以通过\n的形式来获取(n就是组的编号)
捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:
由组可以看出正则表达式的利弊
好处:可以简化对字符串的复杂操作
弊端:符号定义越多,正则越长,阅读性越差
匹配:String matches方法,用规则匹配整个字符串,只要有一处不符合规则,就匹配结束,返回false
splitDemo("zhangsan,lisi,wangwu",",");//用,切割
splitDemo("zhangsan lisi wangwu"," +");//用1个或多个空格切割
splitDemo("zhangsan.lisi.wangwu","\\.");//用.切割
splitDemo("C:\\abc\\a.txt","\\\\");用\\切割
splitDemo("erkkfsdafdasqquidsfooooofsd","(.)\\1+");\1代表第一组
publicstaticvoid splitDemo(String str,String reg){
String[] arr = str.split(reg);
System.out.println(arr.length);
for(String s : arr ){
System.out.println(s);
}
}
替换
String str =
"fdsafasd424235243fsfds74325235342";
replaceAllDemo(str,"\\d{5,}","#");//将str中的至少连续5个以上的数字替换成#,可以用于隐藏别人的电话号码
String str1 =
"erkktyqqqpfdsafk;dsfds....fddddddssffffffffff";
replaceAllDemo(str1,"(.)\\1+","$1");//将字符串中相邻重复元素去除掉$为对前面组的引用\\1为对本规则中的的组的引用
获取:将字符串中的符合规则的子串取出
操作步骤:
1.
将正则表达式封装成对象
2.
让正则对象和要操作的字符串相关联
3.
关联后,获取正则匹配引擎
4.
通过引擎对符合规则的子串进行操作
import java.util.regex.Matcher;
import java.util.regex.Pattern;
publicclass RegexDemo2 {
publicstaticvoid main(String[] args) {
//TODO Auto-generated method stub
getDemo();
}
publicstaticvoid getDemo(){
String str =
"ming tian jiu yao fang jia le ";
System.out.println(str);
String reg =
"\\b[a-z]{4}\\b";//由4个字母组成的单词\b为单词边界
//将规则封装成对象
Pattern p = Pattern.compile(reg);
//让正则对象和要作用的字符串相关联,获取匹配器对象
Matcher m = p.matcher(str);
System.out.println(m.matches());//其实String类中的matches方法,用的就是Pattern和Matcher对象来完成的
//只不过被String的方法封装后,用起来较为简单,但是功能却单一
//boolean b = m.find();将规则作用到字符串上,并进行符合规则的子串查找
//System.out.println(m.group());用于获取匹配后结果
while(m.find()){
System.out.println(m.group());
System.out.println(m.start()+"....."+m.end());
}
}
}
列2个例子用来学习
第一个
import java.util.TreeSet;
publicclass RegexTest {
publicstaticvoid main(String[] args) {
//TODO Auto-generated method stub
// test_1();
ipSort();
}
/*
需求:对邮件地址进行校验
*/
publicstaticvoid checkMail(){
String mail =
"abcd123@sina.com.cn";
String reg =
"[a-zA-Z0-9]+@[a-zA-Z0-9]+(\\.[a-zA-Z0-9]+)+";//较为精确的匹配
//reg = "\\w+@\\w+(\\.\\w)+";相对不太精确的匹配
System.out.println(mail.matches(reg));
}
/*
192.68.1.254 102.49.23.12 10.10.10.10 2.2.2.2 8.109.90.30
将ip地址进行地址段顺序的排序
1,按照每一段需要的最多的0进行补齐,那么每一段就会至少保证有3位
2,将每一段只保留3位,这样,所有的ip地址都是每一段3位
3,最后打印的时候再把每段前面多余的0去掉
*/
publicstaticvoid ipSort(){
String ip =
"192.68.1.254 102.49.23.12 10.10.10.10 2.2.2.2 8.109.90.30";
ip = ip.replaceAll("(\\d+)","00$1");
System.out.println(ip);
ip = ip.replaceAll("0*(\\d{3})","$1");
System.out.println(ip);
String[] arr = ip.split(" +");
for(String ar : arr){
System.out.println(ar);
}
TreeSet<String> ts =
new TreeSet<String>();
for(String ar : arr){
ts.add(ar);
}
for(String s : ts){
System.out.println(s.replaceAll("0*(\\d+)","$1"));
}
}
/*
需求:将指定字符串转成:我要学编程
思路方式:
1,如果只想知道该字符串是对是错,使用匹配
2,想要将已有的字符串变成另一个字符串,替换
3,想要按照自定的方式将字符串变成多个字符串,切割,获取规则以外的子串
4,想要拿到符合需求的字符串子串,获取,获取符合规则的子串
*/
publicstaticvoid test_1(){
String str =
"我我我....我我.我要要...要要....要要要要.学学....学学学...学学.编编....编..程程..程程...";
/*
将已有字符串变成另一个字符串,使用替换功能
1,可以先将.去掉
2,再将多个重复的内容变成单个内容
*/
str = str.replaceAll("\\.+","");
str = str.replaceAll("(.)\\1+","$1");
System.out.println(str);
}
}
第2个
import java.io.*;
import java.net.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
publicclass RegexTest2 {
/**
*
网页爬虫获取网页地址
*/
publicstaticvoid main(String[] args)throws
Exception {
//TODO Auto-generated method stub
getMails_1();
}
publicstaticvoid getMails_1()throws
Exception {
BufferedReader bufIn =
null;
BufferedWriter bufw =
null;
URL url = new URL("http://127.0.0.1:8080/myweb/mail.html");
URLConnection conn = url.openConnection();
bufIn = new BufferedReader(new InputStreamReader(conn.getInputStream()));
bufw = new BufferedWriter(new FileWriter("C:\\爬虫mail.txt",true));
String line = null;
String mailreg =
"\\w+@\\w+(\\.\\w+)+";//邮箱规则的正则表达式
Pattern p = Pattern.compile(mailreg);
while ((line = bufIn.readLine()) !=null)
{
Matcher m = p.matcher(line);
while (m.find()) {
bufw.write(m.group());
bufw.newLine();
bufw.flush();
}
}
bufw.close();
bufIn.close();
}
}
--------- android培训、java培训、期待与您交流!
------------
------------
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
给定一个正则表达式和另一个字符串,我们可以达到如下的目的:
给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”);
可以通过正则表达式,从字符串中获取我们想要的特定部分。
正则表达式的特点是:
1. 灵活性、逻辑性和功能性非常的强;
2. 可以迅速地用极简单的方式达到字符串的复杂控制。
3. 对于刚接触的人来说,比较晦涩难懂。
正则表达式很好用,能够很好的把一些复杂的代码进行简化
比如下面的代码
publicclass RegexDemo {
publicstaticvoid main(String[] args) {
checkQQ();
checkQQ_1();
}
//用正则表达式判断是否与要求匹配
publicstaticvoid checkQQ(){
String qq =
"324203";
String regex =
"[1-9]\\d{4,14}";
boolean flag = qq.matches(regex);
if(flag){
System.out.println(qq+"...is ok");
}
else{
System.out.println(qq+".....非法");
}
}
//自己用语句判断字符串是否与要求匹配
publicstaticvoid checkQQ_1(){
String qq =
"1aaaaaa1";
int len = qq.length();
//判断一个QQ字符串是不是由首位不是0,长度为6-15位的由数字组成的字符串
//先判断长度对不对
if(len>=5 && len<=15){
//判断首位是不是0
if(!qq.startsWith("0")){
char[] arr = qq.toCharArray();
boolean flag =true;
//判断是不是全由数字组成
for(int x = 0;x<arr.length;
x++){
if(!(arr[x]>='0' && arr[x]<='9')){
flag =
false;
break;
}
}
if(flag){
System.out.println("qq:" + qq);
}
else{
System.out.println("出现非法字符");
}
}
else{
System.out.println("不可以0开头");
}
}
else{
System.out.println("长度错误");
}
}
}
由这段代码可以看出正则表达式要比自己去写判断语句简单很多
Sting类里有一些方法
String | replaceAll(String regex, String replacement) 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。 |
String | replaceFirst(String regex, String replacement) 使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。 |
String[] | split(String regex) 根据给定正则表达式的匹配拆分此字符串。 |
String[] | split(String regex, int limit) 根据匹配给定的正则表达式来拆分此字符串。 |
boolean | matches(String regex) 告知此字符串是否匹配给定的正则表达式。 |
由文档可以知道Pattern没有构造函数摘要
所以Pattern肯定提供了获取本类对象的方法compile
方法摘要 | |
static Pattern | compile(String regex) 将给定的正则表达式编译到模式中。 |
static Pattern | compile(String regex, int flags) 将给定的正则表达式编译到具有给定标志的模式中。 |
int | flags() 返回此模式的匹配标志。 |
Matcher | matcher(CharSequence input) 创建匹配给定输入与此模式的匹配器。 |
static boolean | matches(String regex, CharSequence input) 编译给定正则表达式并尝试将给定输入与其匹配。 |
String | pattern() 返回在其中编译过此模式的正则表达式。 |
static String | quote(String s) 返回指定 String 的字面值模式 String。 |
String[] | split(CharSequence input) 围绕此模式的匹配拆分给定输入序列。 |
String[] | split(CharSequence input, int limit) 围绕此模式的匹配拆分给定输入序列。 |
String | toString() 返回此模式的字符串表示形式。 |
可以对单个字符匹配,也可以对多个字符匹配
如reg = “a[a-zA-Z]”表示有两个字符,第一个是a第二个为字母
reg = “[a-zA-Z][a-zA-Z0-9]+”表示第一个为字母,后面为一个或多个字母或数字
reg = “[a-zA-Z_][a-z]{3}”表示第一个为字母,后面有三个小写字母
reg = “[a-zA-Z_][a-z]{3,}”表示第一个为字母,后面至少有三个小写字母
reg = “[a-zA-Z_][a-z]{3,6}”表示第一个为字母,后面至少有三个小写字母最多有6个字母
还有很多的东西,到API文档里看比较详细
Greedy 数量词 | |
X? | X,一次或一次也没有 |
X* | X,零次或多次 |
X+ | X,一次或多次 |
X{n} | X,恰好 n 次 |
X{n,} | X,至少 n 次 |
X{n,m} | X,至少 n 次,但是不超过 m 次 |
“.”是任意字符,所以要想用它只能写成\\.$为组的引用
再说说关于组的概念
reg = "(.)\\1+"为了可以让规则的结果被重用,可以将规则封闭成一个组,用()完成,组的出现都有编号,从1开始,想要使用已有的组可以通过\n的形式来获取(n就是组的编号)
捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:
1 | ((A)(B(C))) |
2 | \A |
3 | (B(C)) |
4 | (C) |
好处:可以简化对字符串的复杂操作
弊端:符号定义越多,正则越长,阅读性越差
匹配:String matches方法,用规则匹配整个字符串,只要有一处不符合规则,就匹配结束,返回false
splitDemo("zhangsan,lisi,wangwu",",");//用,切割
splitDemo("zhangsan lisi wangwu"," +");//用1个或多个空格切割
splitDemo("zhangsan.lisi.wangwu","\\.");//用.切割
splitDemo("C:\\abc\\a.txt","\\\\");用\\切割
splitDemo("erkkfsdafdasqquidsfooooofsd","(.)\\1+");\1代表第一组
publicstaticvoid splitDemo(String str,String reg){
String[] arr = str.split(reg);
System.out.println(arr.length);
for(String s : arr ){
System.out.println(s);
}
}
替换
String str =
"fdsafasd424235243fsfds74325235342";
replaceAllDemo(str,"\\d{5,}","#");//将str中的至少连续5个以上的数字替换成#,可以用于隐藏别人的电话号码
String str1 =
"erkktyqqqpfdsafk;dsfds....fddddddssffffffffff";
replaceAllDemo(str1,"(.)\\1+","$1");//将字符串中相邻重复元素去除掉$为对前面组的引用\\1为对本规则中的的组的引用
获取:将字符串中的符合规则的子串取出
操作步骤:
1.
将正则表达式封装成对象
2.
让正则对象和要操作的字符串相关联
3.
关联后,获取正则匹配引擎
4.
通过引擎对符合规则的子串进行操作
import java.util.regex.Matcher;
import java.util.regex.Pattern;
publicclass RegexDemo2 {
publicstaticvoid main(String[] args) {
//TODO Auto-generated method stub
getDemo();
}
publicstaticvoid getDemo(){
String str =
"ming tian jiu yao fang jia le ";
System.out.println(str);
String reg =
"\\b[a-z]{4}\\b";//由4个字母组成的单词\b为单词边界
//将规则封装成对象
Pattern p = Pattern.compile(reg);
//让正则对象和要作用的字符串相关联,获取匹配器对象
Matcher m = p.matcher(str);
System.out.println(m.matches());//其实String类中的matches方法,用的就是Pattern和Matcher对象来完成的
//只不过被String的方法封装后,用起来较为简单,但是功能却单一
//boolean b = m.find();将规则作用到字符串上,并进行符合规则的子串查找
//System.out.println(m.group());用于获取匹配后结果
while(m.find()){
System.out.println(m.group());
System.out.println(m.start()+"....."+m.end());
}
}
}
列2个例子用来学习
第一个
import java.util.TreeSet;
publicclass RegexTest {
publicstaticvoid main(String[] args) {
//TODO Auto-generated method stub
// test_1();
ipSort();
}
/*
需求:对邮件地址进行校验
*/
publicstaticvoid checkMail(){
String mail =
"abcd123@sina.com.cn";
String reg =
"[a-zA-Z0-9]+@[a-zA-Z0-9]+(\\.[a-zA-Z0-9]+)+";//较为精确的匹配
//reg = "\\w+@\\w+(\\.\\w)+";相对不太精确的匹配
System.out.println(mail.matches(reg));
}
/*
192.68.1.254 102.49.23.12 10.10.10.10 2.2.2.2 8.109.90.30
将ip地址进行地址段顺序的排序
1,按照每一段需要的最多的0进行补齐,那么每一段就会至少保证有3位
2,将每一段只保留3位,这样,所有的ip地址都是每一段3位
3,最后打印的时候再把每段前面多余的0去掉
*/
publicstaticvoid ipSort(){
String ip =
"192.68.1.254 102.49.23.12 10.10.10.10 2.2.2.2 8.109.90.30";
ip = ip.replaceAll("(\\d+)","00$1");
System.out.println(ip);
ip = ip.replaceAll("0*(\\d{3})","$1");
System.out.println(ip);
String[] arr = ip.split(" +");
for(String ar : arr){
System.out.println(ar);
}
TreeSet<String> ts =
new TreeSet<String>();
for(String ar : arr){
ts.add(ar);
}
for(String s : ts){
System.out.println(s.replaceAll("0*(\\d+)","$1"));
}
}
/*
需求:将指定字符串转成:我要学编程
思路方式:
1,如果只想知道该字符串是对是错,使用匹配
2,想要将已有的字符串变成另一个字符串,替换
3,想要按照自定的方式将字符串变成多个字符串,切割,获取规则以外的子串
4,想要拿到符合需求的字符串子串,获取,获取符合规则的子串
*/
publicstaticvoid test_1(){
String str =
"我我我....我我.我要要...要要....要要要要.学学....学学学...学学.编编....编..程程..程程...";
/*
将已有字符串变成另一个字符串,使用替换功能
1,可以先将.去掉
2,再将多个重复的内容变成单个内容
*/
str = str.replaceAll("\\.+","");
str = str.replaceAll("(.)\\1+","$1");
System.out.println(str);
}
}
第2个
import java.io.*;
import java.net.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
publicclass RegexTest2 {
/**
*
网页爬虫获取网页地址
*/
publicstaticvoid main(String[] args)throws
Exception {
//TODO Auto-generated method stub
getMails_1();
}
publicstaticvoid getMails_1()throws
Exception {
BufferedReader bufIn =
null;
BufferedWriter bufw =
null;
URL url = new URL("http://127.0.0.1:8080/myweb/mail.html");
URLConnection conn = url.openConnection();
bufIn = new BufferedReader(new InputStreamReader(conn.getInputStream()));
bufw = new BufferedWriter(new FileWriter("C:\\爬虫mail.txt",true));
String line = null;
String mailreg =
"\\w+@\\w+(\\.\\w+)+";//邮箱规则的正则表达式
Pattern p = Pattern.compile(mailreg);
while ((line = bufIn.readLine()) !=null)
{
Matcher m = p.matcher(line);
while (m.find()) {
bufw.write(m.group());
bufw.newLine();
bufw.flush();
}
}
bufw.close();
bufIn.close();
}
}
--------- android培训、java培训、期待与您交流!
------------
相关文章推荐
- 黑马程序员----API常用类以及正则表达式
- 黑马程序员--正则表达式
- 黑马程序员_91_正则表达式
- 黑马程序员——正则表达式(1)
- 黑马程序员java学习—正则表达式
- 黑马程序员—Java基础—正则表达式
- 黑马程序员——正则表达式
- 黑马程序员——正则表达式
- 黑马程序员_正则表达式
- 黑马程序员——Java基础---正则表达式
- 黑马程序员——Java正则表达式
- 黑马程序员——java基础——正则表达式
- 黑马程序员第三季——正则表达式
- 黑马程序员——正则表达式
- 【黑马程序员】java中-------------正则表达式
- 黑马程序员_正则表达式
- 黑马程序员—正则表达式
- 【黑马程序员】第十一章:正则表达式
- 黑马程序员---正则表达式
- 【黑马程序员】 学习笔记 - Java正则表达式