正则表达式
一、概述。
1、概念:正则表达式是符合一定规则的表达式。
2、特点:用一些特定符号来表示一些代码操作。这样就简化了书写。所以学习正则表达式就是学习一些特殊符号的使用。
3、作用:专门操作字符串的。
4、好处:可以简化对字符串的操作。
6、弊端:符号越多阅读性越差。
二、正则表达式一些常见的匹配规则。
1、字符
x 字符 x
\ 反斜线字符
\t 制表符 (‘\u0009’)
\n 新行(换行)符 (‘\u000A’)
\r 回车符 (‘\u000D’)
\e 转义符 (‘\u001B’)
2、字符类
[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](减去)
3、预定义字符类
. 任何字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9]
\D 非数字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]
4、边界匹配器
^ 行的开头
$ 行的结尾
\b 单词边界
\B 非单词边界
\A 输入的开头
\G 上一个匹配的结尾
\Z 输入的结尾,仅用于最后的结束符(如果有的话)
\z 输入的结尾
5、Greedy 数量词
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过 m 次
6、组和捕获
捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:
1 ((A)(B(C)))
2 \A
3 (B(C))
4 (C)
正则表达式功能示例:匹配,切割,替换和获取。
package 正则表达式;
import java.io.IOException;
import java.io.InputStream;
/**
*
* @author ZHANGYU
* 正则表达式:符合一定规则的表达式。
* 特点:用一些特定符号来表示一些代码操作。这样就简化了书写。
* 所以学习正则表达式就是学习一些特殊符号的使用。
* 作用:专门操作字符串的。
* 好处:可以简化对字符串的操作
* 弊端:符号越多阅读性越差。
* 需求:对qq号进行验证。
* 要求:5-15位 不能0开头 只能为数字。
*
* 具体操作:
* 1 匹配:String matches方法。用规则匹配整个字符串,只能有一处不符合规则匹配结束,返回false
*
*/
public class test1 {
public static void main(String[] args) throws IOException{
String qq="123456789a";
Check1(qq);
check2(qq);
check3(qq);//正则检查qq号
checkTel();//检查手机号
splitDemo("zhang.li.wang","\\.");//按照.切割
splitDemo("zhang li wang"," +");//按照多个空格切割。
splitDemo("c:\\a\\d\\c.txt","\\\\");
splitDemo("asddsjjlkwwaao","(.)\\1");//切割叠词。为了让规则结果被重用,可以将规则封装成一个组,用()完成,组的出现都有编号
splitDemo("asddsjjjlkwwwsaao","(.)\\1+");//从1开始,想要使用已有的组可以通过,\n(n就是组编号)的形式来获取。
String str="sd324234df54345345fgt4343fd435234";//把字符串中的数组替换为#
replaceAllDemo(str,"\\d{5,}","#");//把连续5个或5个以上的数字有#代替
String str1="sdsddwekkl";
replaceAllDemo(str1,"(.)\\1+","#");//将叠词替换成#
}
private static void replaceAllDemo(String str, String strRegx, String newstr) {
// TODO Auto-generated method stub
str=str.replaceAll(strRegx, newstr);
System.out.println(str);
}
private static void splitDemo(String str,String strReg) {
// TODO Auto-generated method stub
String[] s=str.split(strReg);
for(String i:s){
System.out.println(i);
}
}
/*
* 匹配:
* 手机号端有:13xxxxx 15xxxxx 18xxxxx
*/
private static void checkTel() {
// TODO Auto-generated method stub
String tel="13888882134";
String telReg="1[358]\\d{9}";
boolean flage=tel.matches(telReg);//匹配的是整个字符。
System.out.println("tel:"+ flage);
}
//判断QQ号
private static void check3(String qq) {
// TODO Auto-generated method stub
//String regex="[1-9][0-9]{4,14}";
String regex="[1-9]\\d{4,14}";
boolean flage=qq.matches(regex);
if(flage==true)
System.out.println("qq:"+qq);
else
System.out.println("帐号异常");
}
private static void check2(String qq) {
// TODO Auto-generated method stub
if(qq.length()>=5&&qq.length()<=15){
if(!(qq.startsWith("0"))){
try{
Long l=Long.parseLong(qq);
System.out.println("帐号正确");
}catch(NumberFormatException e){
System.out.println("帐号只能为数字");
}
}
else{
System.out.println("帐号开头不能为0");
}
}else
System.out.println("帐号长度不够");
}
private static void Check1(String qq) {
// TODO Auto-generated method stub
if(qq.length()>=5&&qq.length()<=15){
if(!(qq.startsWith("0"))){
char[] ch=qq.toCharArray();
boolean flage=false;
for(int i=0;i<ch.length;i++){
if(ch[i]>='0'&&ch[i]<='9')
flage=true;
else
flage=false;
}
if(flage==true){
System.out.println("帐号正确");
}
else
System.out.println("帐号只能为数字");
}
else{
System.out.println("帐号开头不能为0");
}
}else
System.out.println("帐号长度不够");
}
}
获取功能的示例:
package 正则表达式;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
* 正则表达式的功能:获取
*
*
* 操作步骤:
* 1、将正则表达式封装成对象。
* 2、让正则对象和要操作的字符串相关联。
* 3、关联后,获取正则匹配引擎。
* 4、通过引擎对符合规则的子串进行操作。比如:取出。
*/
public class test3 {
public static void main(String[] args){
Regx();
}
public static void Regx(){
String str="hahaha lwa kd sdi d s ds ew ssd";
String reg="\\b[a-z]{3}\\b";
//将规则封装成对象。
Pattern p=Pattern.compile(reg);
//让正则对象和要作用的字符串相关联。
Matcher m=p.matcher(str);//其实String类中的matches方法,用的就是Pattern和Matcher对象来完成的
//只不过被String方法封装后,用起来较为简单,但是功能比较单一。
//m.find()//将规则作用到字符串上,并进行符合规则的子串查找。
while(m.find()){
System.out.println(m.group());//用于获取匹配后的结果。
System.out.println(m.start()+"-----"+m.end());
}
}
}
正则表达式一些小练习。
练习一:
package 正则表达式;
/*
* 需求:将下列字符串转化为:我要学编程。
*
* 到底用四种功能中的那一个呢?还是那几个呢?
* 思路如下:
* 1、如果只想知道字符串是对还是错,使用匹配。
* 2、想要用已经有的字符串变成新的字符串,替换。
* 3、想要按照自定的方式将字符串变成多个字符串。切割,获取规则以外的子串。
* 4、想要拿到符合需求的字符串子串。获取。获取符合规则的子串。
*
*/
public class test4 {
public static void main(String[] args){
String str="我我...我我...我我...我我.......要要学学学....编编...编程...程程....程";
/*
* 思路:
* 将已经有的字符串变成新的字符串用--替换。
* 1、可以先把.去掉
* 2、再将多个重复的内容变成单个内容。
*
*/
str=str.replaceAll("\\.+", "");
System.out.println(str);
str=str.replaceAll("(.)\\1+", "$1");
System.out.println(str);
}
}
练习二:
package 正则表达式;
import java.util.TreeSet;
public class test5 {
public static void main(String[] args){
ipSort();
emal();
}
private static void emal() {
// TODO Auto-generated method stub
/*
* 对邮箱地址进行校验
*
*/
String str="skd21@sina.com";
String Regx="[a-zA-Z0-9_]+@[a-zA-Z0-9_]+(\\.[a-zA-Z0-9_]+)+";//较为精确的匹配方式
String Regx1="\\w+@\\w+(\\.\\w+)+";//相对不太精确的匹配方式
System.out.println(str.matches(Regx));
}
private static void ipSort() {
// TODO Auto-generated method stub
/*
* 192.168.1.254 102.49.23.013 10.10.10.10 2.2.2.2. 8.109.90.30
* 将ip地址进行地段顺序排序。
*
* 还是按照字符串自然顺序,只要让它们每一段都是三位即可。
* 1、按照每一段需要的最多的0进行补齐,那么每一段就会至少保证有三位
* 2、将每一段只保留三位,这样所有的ip地址就会每一段都三位。
*/
String ip="192.168.1.254 102.49.23.013 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(" +");
TreeSet<String> ts=new TreeSet<String>();
for(String s:arr)
ts.add(s);
for(String s:ts)
System.out.println(s.replaceAll("0*(\\d+)", "$1"));
}
}
练习三:获取一些邮箱地址。
package 正则表达式;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
* 网页爬虫(蜘蛛)
*/
public class test6 {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
getMile();
getMile_1();
}
private static void getMile_1() throws Exception {
// TODO Auto-generated method stub
URL url=new URL("网页地址");//封装网页地址
URLConnection conn=url.openConnection(); //连接服务器
BufferedReader bufr=new BufferedReader(new InputStreamReader(conn.getInputStream()));//带缓冲区的网页读取流
String regx="\\w+@\\w+(\\.\\w+)+";
Pattern p=Pattern.compile(regx);//创建Pattern对象,封装正则表达式
String line=null;
while((line=bufr.readLine())!=null){
Matcher m=p.matcher(line);
while(m.find())
System.out.println(m.group());
}
}
private static void getMile() throws Exception {
// TODO Auto-generated method stub
BufferedReader bur=new BufferedReader(new FileReader("mail.txt"));
String line=null;
String regx="\\w+@\\w+(\\.\\w+)+";
Pattern p=Pattern.compile(regx);
while((line=bur.readLine())!=null){
Matcher m=p.matcher(line);
while(m.find())
System.out.println(m.group());
}
}
}