您的位置:首页 > 职场人生

黑马程序员__正则表达式

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类里有一些方法

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()

返回此模式的字符串表示形式。

那怎么定义正则表达式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文档里看比较详细

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培训、期待与您交流!
------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: