网络编程 
首页 > 网络编程 > 浏览文章

深入浅解正则表达式在Java中的使用

(编辑:jimmy 日期: 2024/11/28 浏览:3 次 )

介绍

"color: #ff0000">从简单例子认识正则表达式匹配

"htmlcode">

public class Demo1 {
 public static void main(String[] args) {
 //字符串abc匹配正则表达式"...", 其中"."表示一个字符
 //"..."表示三个字符
 System.out.println("abc".matches("..."));

 System.out.println("abcd".matches("..."));
 }
}
//输出结果
true
false

"color: #ff0000">Java中对正则表达式的支持(各种语言有相应的实现)

"htmlcode">

public class Demo1 {
 public static void main(String[] args) {
 //字符串abc匹配正则表达式"...", 其中"."表示一个字符
 //"..."表示三个字符
 System.out.println("abc".matches("..."));

 System.out.println("abcd".matches("..."));
 }
}
//输出结果
true
false

"abc".matches("[a-z]{3}"));
"color: #ff0000">初步认识 . + * "htmlcode">

public class Demo3 {
 /**
 * 为了省略每次写打印语句, 这里把输出语句封装起来
 * @param o
 */
 private static void p(Object o){
 System.out.println(o);
 }

 /**
 * . Any character (may or may not match line terminators), 任意字符
 * X"a".matches("."));
 p("aa".matches("aa"));
 p("aaaa".matches("a*"));
 p("aaaa".matches("a+"));
 p("".matches("a*"));
 p("a".matches("a"));

 // \d A digit: [0-9], 表示数字, 但是在java中对"\"这个符号需要使用\进行转义, 所以出现\\d
 p("2345".matches("\\d{2,5}"));
 // \\.用于匹配"."
 p("192.168.0.123".matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"));
 // [0-2]指必须是0~2中的一个数字
 p("192".matches("[0-2][0-9][0-9]"));
 }
}
//输出结果
//全为true

范围

"htmlcode">

public class Demo4 {
 private static void p(Object o){
 System.out.println(o);
 }

 public static void main(String[] args) {
 //[abc]指abc中的其中一个字母
 p("a".matches("[abc]"));
 //[^abc]指除了abc之外的字符
 p("1".matches("[^abc]"));
 //a~z或A~Z的字符, 以下三个均是或的写法
 p("A".matches("[a-zA-Z]"));
 p("A".matches("[a-z|A-Z]"));
 p("A".matches("[a-z[A-Z]]"));
 //[A-Z&&[REQ]]指A~Z中并且属于REQ其中之一的字符
 p("R".matches("[A-Z&&[REQ]]"));
 }
}
//输出结果

全部为true

认识\s \w \d - 下面介绍数字和字母的正则表达, 这是编程中使用最多的字符了.

关于\

"老师大声说:"同学们,快交作业!"". 如果我们没有转义字符, 那么开头的双引号的结束应该在说:"这里, 但是我们的字符串中需要用到双引号, 所以需要用转义字符
"老师大声说:\"同学们,快交作业!\"", 这样我们的原意才能被正确识别.
"\\"
"\\\\".
"htmlcode">

public class Demo5 {
 private static void p(Object o){
 System.out.println(o);
 }

 public static void main(String[] args) {
 /**
 * \d A digit: [0-9] 数字
 * \D A non-digit: [^0-9] 非数字
 * \s A whitespace character: [ \t\n\x0B\f\r] 空格
 * \S A non-whitespace character: [^\s] 非空格
 * \w A word character: [a-zA-Z_0-9] 数字字母和下划线
 * \W A non-word character: [^\w] 非数字字母和下划线
 */
 // \\s{4}表示4个空白符
 p(" \n\r\t".matches("\\s{4}"));
 // \\S表示非空白符
 p("a".matches("\\S"));
 // \\w{3}表示数字字母和下划线
 p("a_8".matches("\\w{3}"));
 p("abc888&^%".matches("[a-z]{1,3}\\d+[%^&*]+"));
 // 匹配  p("\\".matches("\\\\"));
 }
}
//输出结果

全部为true

边界处理

"htmlcode">

public class Demo6 {
 private static void p(Object o){
 System.out.println(o);
 }

 public static void main(String[] args) {
 /**
 * ^ The beginning of a line 一个字符串的开始
 * $ The end of a line 字符串的结束
 * \b A word boundary 一个单词的边界, 可以是空格, 换行符等
 */
 p("hello sir".matches("^h.*"));
 p("hello sir".matches(".*r$"));
 p("hello sir".matches("^h[a-z]{1,3}o\\b.*"));
 p("hellosir".matches("^h[a-z]{1,3}o\\b.*"));
 }
}

练习:匹配空白行合email地址

" \n".matches("^[\\s&&[^\n]]*\\n$"));
"external nofollow" href="file://\\n$">\\n$最后以换行符结束
"liuyj24@126.com".matches("[\\w[.-]]+@[\\w[.-]]+\\.[\\w]+"));
"htmlcode">

public class Demo8 {
 private static void p(Object o){
 System.out.println(o);
 }

 public static void main(String[] args) {
 Pattern pattern = Pattern.compile("\\d{3,5}");
 String s = "123-34345-234-00";
 Matcher m = pattern.matcher(s);

 //先演示matches(), 与整个字符串匹配.
 p(m.matches());
 //结果为false, 显然要匹配3~5个数字会在-处匹配失败

 //然后演示find(), 先使用reset()方法把当前位置设置为字符串的开头
 m.reset();
 p(m.find());//true 匹配123成功
 p(m.find());//true 匹配34345成功
 p(m.find());//true 匹配234成功
 p(m.find());//false 匹配00失败

 //下面我们演示不在matches()使用reset(), 看看当前位置的变化
 m.reset();//先重置
 p(m.matches());//false 匹配整个字符串失败, 当前位置来到-
 p(m.find());// true 匹配34345成功
 p(m.find());// true 匹配234成功
 p(m.find());// false 匹配00始边
 p(m.find());// false 没有东西匹配, 失败

 //演示lookingAt(), 从头开始找
 p(m.lookingAt());//true 找到123, 成功
 }
}

Matcher类中的start()和end()

"htmlcode">

public class Demo9 {
 private static void p(Object o){
 System.out.println(o);
 }

 public static void main(String[] args) {
 Pattern pattern = Pattern.compile("\\d{3,5}");
 String s = "123-34345-234-00";
 Matcher m = pattern.matcher(s);

 p(m.find());//true 匹配123成功
 p("start: " + m.start() + " - end:" + m.end());
 p(m.find());//true 匹配34345成功
 p("start: " + m.start() + " - end:" + m.end());
 p(m.find());//true 匹配234成功
 p("start: " + m.start() + " - end:" + m.end());
 p(m.find());//false 匹配00失败
 try {
 p("start: " + m.start() + " - end:" + m.end());
 }catch (Exception e){
 System.out.println("报错了...");
 }
 p(m.lookingAt());
 p("start: " + m.start() + " - end:" + m.end());
 }
}
//输出结果
true
start: 0 - end:3
true
start: 4 - end:9
true
start: 10 - end:13
false
报错了...
true
start: 0 - end:3

替换字符串

"htmlcode">

public class Demo10 {
 private static void p(Object o){
 System.out.println(o);
 }

 public static void main(String[] args) {
 Pattern p = Pattern.compile("java");
 Matcher m = p.matcher("java Java JAVA JAva I love Java and you");
 p(m.replaceAll("JAVA"));//replaceAll()方法会替换所有匹配到的字符串
 }
}
//输出结果
JAVA Java JAVA JAva I love Java and you

升级: 不区分大小写查找并替换字符串

"java", Pattern.CASE_INSENSITIVE);//指定为大小写不敏感的
 Matcher m = p.matcher("java Java JAVA JAva I love Java and you");
 p(m.replaceAll("JAVA"));
}
//输出结果
JAVA JAVA JAVA JAVA I love JAVA and you

再升级: 不区分大小写, 替换查找到的指定字符串

"htmlcode">

public static void main(String[] args) {
 Pattern p = Pattern.compile("java", Pattern.CASE_INSENSITIVE);
 Matcher m = p.matcher("java Java JAVA JAva I love Java and you ");
 StringBuffer sb = new StringBuffer();
 int index = 1;
 while(m.find()){
 //m.appendReplacement(sb, (index++ & 1) == 0 "java" : "JAVA"); 较为简洁的写法
 if((index & 1) == 0){//偶数
 m.appendReplacement(sb, "java");
 }else{
 m.appendReplacement(sb, "JAVA");
 }
 index++;
 }
 m.appendTail(sb);//把剩余的字符串加入
 p(sb);
}
//输出结果
JAVA java JAVA java I love JAVA and you "color: #ff0000">分组

"htmlcode">

public static void main(String[] args) {
 Pattern p = Pattern.compile("\\d{3,5}[a-z]{2}");
 String s = "123aa-5423zx-642oi-00";
 Matcher m = p.matcher(s);
 while(m.find()){
 p(m.group());
 }
}
//输出结果
123aa
5423zx
642oi

"\\d{3,5}[a-z]{2}"表示3~5个数字跟上两个字母, 然后打印出每个匹配到的字符串.
"(\\d{3,5})([a-z]{2})"
"htmlcode">

public static void main(String[] args) {
 Pattern p = Pattern.compile("(\\d{3,5})([a-z]{2})");//正则表达式为3~5个数字跟上两个字母
 String s = "123aa-5423zx-642oi-00";
 Matcher m = p.matcher(s);
 while(m.find()){
 p(m.group(1));
 }
}
//输出结果
123
5423
642

实战1: 抓取网页中的email地址(爬虫)

"htmlcode">

public class Demo12 {
 public static void main(String[] args) {
 BufferedReader br = null;
 try {
 br = new BufferedReader(new FileReader("C:\\emailTest.html"));
 String line = "";
 while((line = br.readLine()) != null){//读取文件的每一行
 parse(line);//解析其中的email地址
 }
 } catch (FileNotFoundException e) {
 e.printStackTrace();
 } catch (IOException e) {
 e.printStackTrace();
 }finally {
 if(br != null){
 try {
  br.close();
  br = null;
 } catch (IOException e) {
  e.printStackTrace();
 }
 }
 }
 }

 private static void parse(String line){
 Pattern p = Pattern.compile("[\\w[.-]]+@[\\w[.-]]+\\.[\\w]+");
 Matcher m = p.matcher(line);
 while(m.find()){
 System.out.println(m.group());
 }
 }
}
//输出结果
2819531636@qq.com
2819531636@qq.com
2405059759@qq.com
2405059759@qq.com
1013376804@qq.com
...

实战2: 代码统计小程序

"htmlcode">

public class Demo13 {
 private static long codeLines = 0;
 private static long commentLines = 0;
 private static long whiteLines = 0;
 private static String filePath = "C:\\TankOnline";
 public static void main(String[] args) {
 process(filePath);
 System.out.println("codeLines : " + codeLines);
 System.out.println("commentLines : " + commentLines);
 System.out.println("whiteLines : " + whiteLines);
 }
 /**
 * 递归查找文件
 * @param pathStr
 */
 public static void process(String pathStr){
 File file = new File(pathStr);
 if(file.isDirectory()){//是文件夹则递归查找
 File[] fileList = file.listFiles();
 for(File f : fileList){
 String fPath = f.getAbsolutePath();
 process(fPath);
 }
 }else if(file.isFile()){//是文件则判断是否是.java文件
 if(file.getName().matches(".*\\.java$")){
 parse(file);
 }
 }
 }
 private static void parse(File file) {
 BufferedReader br = null;
 try {
 br = new BufferedReader(new FileReader(file));
 String line = "";
 while((line = br.readLine()) != null){
 line = line.trim();//清空每行首尾的空格
 if(line.matches("^[\\s&&[^\\n]]*$")){//注意不是以\n结尾, 因为在br.readLine()会去掉\n
  whiteLines++;
 }else if(line.startsWith("/*") || line.startsWith("*") || line.endsWith("*/")){
  commentLines++;
 }else if(line.startsWith("//") || line.contains("//")){
  commentLines++;
 }else{
  if(line.startsWith("import") || line.startsWith("package")){//导包不算
  continue;
  }
  codeLines++;
 }
 }
 } catch (FileNotFoundException e) {
 e.printStackTrace();
 } catch (IOException e) {
 e.printStackTrace();
 } finally {
 if(null != br){
 try {
  br.close();
  br = null;
 } catch (IOException e) {
  e.printStackTrace();
 }
 }
 }
 }
}
//输出结果
codeLines : 1139
commentLines : 124
whiteLines : 172

贪婪模式与非贪婪模式

"color: #ff0000">Reluctant quantifiers 非贪婪模式(勉强的, 不情愿的)

X"htmlcode">

public static void main(String[] args) {
 Pattern p = Pattern.compile(".{3,10}[0-9]");
 String s = "aaaa5bbbb6";//10个字符
 Matcher m = p.matcher(s);
 if(m.find()){
 System.out.println(m.start() + " - " + m.end());
 }else {
 System.out.println("not match!");
 }
}
//输出结果
0 - 10

"htmlcode">

public static void main(String[] args) {
 Pattern p = Pattern.compile(".{3,10}");//添加了一个"aaaa5bbbb6";
 Matcher m = p.matcher(s);
 if(m.find()){
 System.out.println(m.start() + " - " + m.end());
 }else {
 System.out.println("not match!");
 }
}
//输出结果
0 - 5

"htmlcode">

public static void main(String[] args) {
 Pattern p = Pattern.compile(".{3,10}+[0-9]");//多了个+
 String s = "aaaa5bbbb6";
 Matcher m = p.matcher(s);
 if(m.find()){
 System.out.println(m.start() + " - " + m.end());
 }else {
 System.out.println("not match!");
 }
}
//输出结果
not match!

"color: #ff0000">总结

以上所述是小编给大家介绍的正则表达式在Java中的使用,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

上一篇:常用JavaScript正则表达式汇编与示例详解
下一篇:javascript正则表达式学习之位置匹配
高通和谷歌日前宣布,推出首次面向搭载骁龙的Windows PC的优化版Chrome浏览器。
在对骁龙X Elite参考设计的初步测试中,全新的Chrome浏览器在Speedometer 2.1基准测试中实现了显著的性能提升。
预计在2024年年中之前,搭载骁龙X Elite计算平台的PC将面世。该浏览器的提前问世,有助于骁龙PC问世就获得满血表现。
谷歌高级副总裁Hiroshi Lockheimer表示,此次与高通的合作将有助于确保Chrome用户在当前ARM兼容的PC上获得最佳的浏览体验。