JAVA笔记27-正则表达式(RegularExpressions)
正则表达式是字符串的处理利器。
用途:字符串匹配(字符匹配)、字符串查找、字符串替换
例如:IP地址是否正确、从网页中揪出email地址(如垃圾邮件)、从网页中揪出链接等
涉及到的类:java.lang.String, java.util.regex.Pattern, java.util.regex.Matcher
例1:Pattern是模式,Matcher是与模式匹配后的结果。
典型的调用顺序是
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();
import java.util.regex.*;
public class Test{
public static void main(String args[]){
System.out.println("abc".matches("..."));
System.out.println("a3435f".replaceAll("\\d","-"));
Pattern p = Pattern.compile("[a-z]{3}");
Matcher m = p.matcher("fgh");
System.out.println(m.matches());
System.out.println("fgha".matches("[a-z]{3}"));
}
}
输出:
true
a----f
true
false
例2:
| X? | X,一次或一次也没有 |
| X* | X,零次或多次 |
| X+ | X,一次或多次 |
| X{n} | X,恰好 n 次 |
| X{n,} | X,至少 n 次 |
| X{n,m} | X,至少 n 次,但是不超过 m 次 |
import java.util.regex.*;
public class Test{
public static void main(String args[]){
//?={0,1}, *={0,}, +={1,}
System.out.println("a".matches("."));
System.out.println("aa".matches("aa"));
System.out.println("aaaa".matches("a*"));
System.out.println("aaaa".matches("a+"));
System.out.println("aaaa".matches("a?")); //false
System.out.println("".matches("a*"));
System.out.println("".matches("a?"));
System.out.println("a".matches("a?"));
System.out.println("2455668678".matches("\\d{3,100}"));
System.out.println("192.168.0.aaa".matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"));//false
System.out.println("192".matches("[0-2][0-9][0-9]"));
}
}
例3:[]代表其中任何一个字符,[^]代表除这些以外的一个字符
| [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](减去) |
import java.util.regex.*;
public class Test{
public static void main(String args[]){
System.out.println("a".matches("[abc]"));
System.out.println("a".matches("[^abc]")); //除abc false
System.out.println("A".matches("[a-zA-Z]"));
System.out.println("A".matches("[a-z]|[A-Z]"));
System.out.println("A".matches("[a-z[A-Z]]"));
System.out.println("R".matches("[A-Z&&[RFG]]"));
}
}
例4:
| \d | 数字:[0-9] |
| \D | 非数字: [^0-9] |
| \s | 空白字符:[ \t\n\x0B\f\r] |
| \S | 非空白字符:[^\s] |
| \w | 单词字符:[a-zA-Z_0-9] |
| \W | 非单词字符:[^\w] |
import java.util.regex.*;
public class Test{
public static void main(String args[]){
System.out.println(" \n\r\t".matches("\\s{4}"));
System.out.println(" ".matches("\\S")); // false
System.out.println("a_8".matches("\\w{3}"));
System.out.println("abc888&^%".matches("[a-z]{1,3}\\d+[&^#%]+"));
System.out.println("\\".matches("\\\\"));
}
}
注意:正则表达式中,要匹配一个\,必须要用\\。而用字符串表示正则表达式时,正则表达式中的一个\就需要字符串中的两个\
例5:POSIX字符类(不常用)
| \p{Lower} | 小写字母字符:[a-z] |
| \p{Upper} | 大写字母字符:[A-Z] |
| \p{ASCII} | 所有 ASCII:[\x00-\x7F] |
| \p{Alpha} | 字母字符:[\p{Lower}\p{Upper}] |
| \p{Digit} | 十进制数字:[0-9] |
| \p{Alnum} | 字母数字字符:[\p{Alpha}\p{Digit}] |
| \p{Punct} | 标点符号:!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ |
| \p{Graph} | 可见字符:[\p{Alnum}\p{Punct}] |
| \p{Print} | 可打印字符:[\p{Graph}\x20] |
| \p{Blank} | 空格或制表符:[ \t] |
| \p{Cntrl} | 控制字符:[\x00-\x1F\x7F] |
| \p{XDigit} | 十六进制数字:[0-9a-fA-F] |
| \p{Space} | 空白字符:[ \t\n\x0B\f\r] |
import java.util.regex.*;
public class Test{
public static void main(String args[]){
System.out.println("a".matches("\\p{Lower}"));
}
}
例6:边界匹配
| ^ | 行的开头 |
| $ | 行的结尾 |
| \b | 单词边界 |
| \B | 非单词边界 |
| \A | 输入的开头 |
| \G | 上一个匹配的结尾 |
| \Z | 输入的结尾,仅用于最后的结束符(如果有的话) |
| \z | 输入的结尾 |
注:^在[]中是取反的意思,在[]外表示行的开头。
import java.util.regex.*;
public class Test{
public static void main(String args[]){
System.out.println("hello sir".matches("^h.*"));
System.out.println("hello sir".matches(".*ir$"));
System.out.println("hello sir".matches("^h[a-z]{1,3}o\\b.*"));
System.out.println("hellosir".matches("^h[a-z]{1,3}o\\b.*")); //false
System.out.println(" \n".matches("^[\\s&&[^\\n]]*\\n$"));//空白行
}
}
练习1:true or false?
import java.util.regex.*;
public class Test{
public static void main(String args[]){
System.out.println("aaa 8888c".matches(".*\\d{4}."));
System.out.println("aaa 8888c".matches(".*\\b\\d{4}.")); //true!
System.out.println("aaa 8888c".matches(".{3}\\b\\d{4}.")); //false
System.out.println("aaa8888c".matches(".*\\d{4}."));
System.out.println("aaa8888c".matches(".*\\b\\d{4}.")); //false
}
}
例7:matches find lookingAt
matches是匹配整个字符串,find是找子串,两者会相互影响,它们都会吃掉已经判断过的字符串。
find不必须从头开始匹配,只要找到匹配的就可以
lookingAt每次都从开头找
import java.util.regex.*;
public class Test{
public static void main(String args[]){
String s = "123-34545-234-00";
Pattern p = Pattern.compile("\\d{3,5}");
Matcher m = p.matcher(s);
System.out.println(m.matches());//false
m.reset();
System.out.println(m.find());
System.out.println(m.find());
System.out.println(m.find());
System.out.println(m.find()); //false
System.out.println(m.lookingAt());
System.out.println(m.lookingAt());
System.out.println(m.lookingAt());
System.out.println(m.lookingAt());
}
}
import java.util.regex.*;
public class Test{
public static void main(String args[]){
String s = "123-34545-234-00";
Pattern p = Pattern.compile("\\d{3,5}");
Matcher m = p.matcher(s);
System.out.println(m.matches());//false
//m.reset();
System.out.println(m.find());
System.out.println(m.find());
System.out.println(m.find()); //false
System.out.println(m.find()); //false
System.out.println(m.lookingAt());
System.out.println(m.lookingAt());
System.out.println(m.lookingAt());
System.out.println(m.lookingAt());
}
}
例8:[start end) 包含start,不包含end
import java.util.regex.*;
public class Test{
public static void main(String args[]){
String s = "123--34545--234-00";
Pattern p = Pattern.compile("\\d{3,5}");
Matcher m = p.matcher(s);
System.out.println(m.matches());//false
m.reset();
System.out.println(m.find());
System.out.println(m.start()+"-"+m.end());
System.out.println(m.find());
System.out.println(m.start()+"-"+m.end());
System.out.println(m.find());
System.out.println(m.start()+"-"+m.end());
System.out.println(m.find()); //false
System.out.println(m.lookingAt());
System.out.println(m.lookingAt());
System.out.println(m.lookingAt());
System.out.println(m.lookingAt());
}
}
输出:
false
true
0-3
true
5-10
true
12-15
false
true
true
true
true
例9:替换
(1)
import java.util.regex.*;
public class Test{
public static void main(String args[]){
Pattern p = Pattern.compile("java");
Matcher m = p.matcher("java Java JAva java IloveJAVA YOUhatejavajava end");
while(m.find()){
System.out.println(m.group());
}
}
}
输出:
java
java
java
java
(2)
import java.util.regex.*;
public class Test{
public static void main(String args[]){
Pattern p = Pattern.compile("java",Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher("java Java JAva java IloveJAVA YOUhatejavajava end");
while(m.find()){
System.out.println(m.group());
}
}
}
输出:
java
Java
JAva
java
JAVA
java
java
(3)
import java.util.regex.*;
public class Test{
public static void main(String args[]){
Pattern p = Pattern.compile("java",Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher("java Java JAva java IloveJAVA YOUhatejavajava end");
System.out.println(m.replaceAll("JAVA"));
}
}
输出:
JAVA JAVA JAVA JAVA IloveJAVA YOUhateJAVAJAVA end
(4)
import java.util.regex.*;
public class Test{
public static void main(String args[]){
Pattern p = Pattern.compile("java",Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher("java Java JAva java IloveJAVA YOUhatejavajava end");
StringBuffer buf = new StringBuffer();
int i = 0 ;
while(m.find()){
i++;
if(i%2 == 0){
m.appendReplacement(buf,"java");
}else{
m.appendReplacement(buf,"JAVA");
}
}
m.appendTail(buf);
System.out.println(buf);
}
}
输出:
JAVA java JAVA java IloveJAVA YOUhatejavaJAVA end
例10:分组:标号是左小括号数。
import java.util.regex.*;
public class Test{
public static void main(String args[]){
Pattern p = Pattern.compile("(\\d{3,5})([a-z]{2})");
String s = "123aa-34556bb-456cc-00";
Matcher m = p.matcher(s);
while(m.find()){
System.out.println(m.group(1));
} }
}
输出:
123
34556
456
如果是group(),则输出
123aa
34556bb
456cc
练习1:抓取网页中的email地址
import java.util.regex.*;
import java.io.*;
public class Test{
public static void main(String args[]){
try{
BufferedReader br = new BufferedReader(new FileReader("abc.htm"));
String s = null ;
while((s = br.readLine())!= null){
parse(s);
}
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
private static void parse(String s){
Pattern p = Pattern.compile("[\\w[.-]]+@[\\w[.-]]+\\.[\\w]+");
Matcher m = p.matcher(s);
while(m.find()){
System.out.println(m.group());
}
}
}
存入文件:
import java.util.regex.*;
import java.io.*;
public class Test{
public static void main(String args[]){
try{
BufferedReader br = new BufferedReader(new FileReader("abc.htm"));
BufferedWriter bw = new BufferedWriter(new FileWriter("email.txt"));
String s = null ;
while((s = br.readLine())!= null){
parse(s,bw);
}
bw.close();
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
private static void parse (String s, BufferedWriter bw) throws IOException{
Pattern p = Pattern.compile("[\\w[.-]]+@[\\w[.-]]+\\.[\\w]+");
Matcher m = p.matcher(s);
while(m.find()){
bw.write(m.group());
bw.newLine();
}
bw.flush();
}
}
练习2:统计代码行数
import java.util.regex.*;
import java.io.*;
public class CodeCounter{
static long normalLines = 0;
static long commentLines = 0;
static long whiteLines = 0;
public static void main(String args[]){
File f = new File("E:/javacode/20140426");
File[] codeFiles = f.listFiles();
for(File child : codeFiles){
if(child.getName().matches(".*\\.java$"))
parse(child);
}
System.out.println("normalLines: "+normalLines);
System.out.println("commentLines: "+commentLines);
System.out.println("whiteLines: "+whiteLines);
} private static void parse(File f){
BufferedReader br = null ;
boolean comment = false;
try{
br = new BufferedReader(new FileReader(f));
String line = "";
while((line = br.readLine())!=null){
line = line.trim();
if(line.matches("^[\\s&&[^\\n]]*$")){
whiteLines++;
}else if(line.startsWith("/*")&&line.endsWith("*/")){
commentLines++;
}else if(line.startsWith("/*")&&!line.endsWith("*/")){
commentLines++;
comment=true;
}else if(true == comment){
commentLines++;
if(line.endsWith("*/")){
comment=false;
}
}else if(line.startsWith("//")){
commentLines++;
}else{
normalLines++;
}
}
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}finally{
if(br!=null){
try{
br.close();
br=null;
}catch(IOException e){
e.printStackTrace();
}
}
}
}
}
JAVA笔记27-正则表达式(RegularExpressions)的更多相关文章
- JAVA自学笔记27
JAVA自学笔记27 1.类的加载 1)当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. ①加载:就是指将class文件读入内存,并为之创 ...
- 【java学习笔记】正则表达式
一.正则表达式 1.预定义字符集 . 表示任意一个字符 \d 表示任意一个数字 \w 表示任意一个单词字符(只能是数字.字母.下划线) \s 表示任意一个空白字符(\t\r\n\f\x0B) \D ...
- (转)Java中使用正则表达式的一个简单例子及常用正则分享
转自:http://www.jb51.net/article/67724.htm 这篇文章主要介绍了Java中使用正则表达式的一个简单例子及常用正则分享,本文用一个验证Email的例子讲解JAVA中如 ...
- MOOC JAVA笔记
MOOC JAVA笔记 1.基础了解 JDK是开发人员安装的,它提供了开发java程序的必须工具 JRE是普通用户安装的,它提供了java的运行环境 JVM是java虚拟机运行程序的核心 2.程序的移 ...
- Effective Java笔记一 创建和销毁对象
Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...
- 9.JAVA中的正则表达式
一.JAVA中的正则表达式 1.概念:以某种特定的方式描述字符串 1.Java中正则表达式的规则 ? #{0,1}-?有一个-或者没有 \\ #表示一个" ...
- Java笔记9-正则表达式
提纲: 1.正则表达式 2.常见的异常 3.内部类------------------------------------------------------------------JDK 1.4以后 ...
- java密码验证正则表达式校验
,正则表达式就是记录文本规则的代码.php密码验证正则表达式(8位长度限制)<?php //密码验证 $password = "zongzi_Abc_oo13a2"; $n ...
- java笔记00-目录
--2013年7月26日17:49:59 学习java已久,趁最近有空,写一个总结: java笔记01-反射:
- JAVA自动生成正则表达式工具类
经过很久的努力,终于完成了JAVA自动生成正则表达式工具类.还记得之前需要正则,老是从网上找吗?找了想修改也不会修改.现在不用再为此烦恼了,使用此生成类轻松搞定所有正则表达式.赶快在同事面前炫一下吧. ...
随机推荐
- java:Mybatis框架1(基本配置,log4j,Junit4(单元测试))
1.mybatis01: db.properties: driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/test userna ...
- MyBatis框架原理2:SqlSession运行过程
获取SqlSession对象 SqlSession session = sqlSessionFactory.openSession(); 首先通过SqlSessionFactory的openSessi ...
- 【MM系列】SAP S/4 HANA 1511的BP角色创建及供应商数据的创建方法
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP S/4 HANA 1511的 ...
- lua基础学习(三)
一.lua函数 1.在Lua中,函数是对语句和表达式进行抽象的主要方法.既可以用来处理一些特殊的工作,也可以用来计算一些值.Lua 提供了许多的内建函数,你可以很方便的在程序中调用它们,如print( ...
- Solrcloud+tomcat+zookeeper
准备两台服务器,目录结构如下 主机名 IP地址 tomcat安装路径 zookeeper安装路径 solr安装路径 java安装路径 sht-sgmhadoopnn-01 172.16.101.55 ...
- sql server CDC报错:超出存储过程、函数、触发器的最大嵌套层数(最大层为32)
sys.sp_MScdc_capture_job RAISERROR(22801, 10, -1) --原本 go sys.sp_MScdc_capture_job; go --修改后 ...
- 再谈PG索引-存储架构
1.索引的基本架构 PG的索引是B+树,B+树是为磁盘或其他直接存取辅助设备而设计的一种平衡查找树,在B+树中,所有记录节点都是按键值的大小顺序存放在同一层的叶节点中,各叶节点指针进行连接: meta ...
- POJ - 1287 Networking (最小生成树&并查集
You are assigned to design network connections between certain points in a wide area. You are given ...
- Codeforces 1140F Extending Set of Points (线段树分治+并查集)
这题有以下几个步骤 1.离线处理出每个点的作用范围 2.根据线段树得出作用范围 3.根据分治把每个范围内的点记录和处理 #include<bits/stdc++.h> using name ...
- Centos7安装Swoole
准备:安装好php后,还需要将PHP的可执行目录添加到环境变量中. //打开文件 vi ~/.bashrc //在文件末尾添加这两行,保存退出 export PATH=/usr/local/php/b ...