【第十三天】正则表达式
复习:
1. String:字符串是一个常量,定义好之后不可改变;因为字符串是不可变的,所以是被共享的。确定String创建对象的个数;字符串的拼接问题--- StringBuffer/StringBuilder是一个可变的字符数组 --- StringBuilder是线程不安全的,拼接效率相对较高;StringBuffer是线程安全的,拼接效率相对较低。
正则表达式---Regex
Regex --- regular expression --- Pattern
指定的规则,利用指定好的规则来进行匹配或者筛选的过程---会写一些简单正则即可
在线正则生成网站:http://www.txt2re.com/
1 package cn.tedu.regex; 2 3 import java.util.regex.Matcher; 4 import java.util.regex.Pattern; 5 6 public class PatternDemo1 { 7 8 public static void main(String[] args) { 9 10 String str = "bez"; 11 12 // 判断一个字符串是否是字符a 13 // System.out.println(str.equals("a")); 14 // Pattern p = Pattern.compile("a"); 15 // Matcher m = p.matcher(str); 16 // System.out.println(m.matches()); 17 18 // 判断一个字符串是否是"abc" 19 // System.out.println(str.equals("abc")); 20 // Pattern p = Pattern.compile("abc"); 21 // Matcher m = p.matcher(str); 22 // System.out.println(m.matches()); 23 24 // 匹配 abc/def/xyz组成的字符串 25 // Pattern p = Pattern.compile("[abc][def][xyz]"); 26 // Matcher m = p.matcher(str); 27 // System.out.println(m.matches()); 28 // System.out.println(str.matches("[cba][edf][xyz]")); 29 30 // 匹配由一个小写字母组成的字符串 31 System.out.println(str.length() == 1 && str.charAt(0) >= 'a' &&str.charAt(0) <= 'z'); 32 System.out.println(str.matches("[a-z]")); 33 34 // 匹配除了a/b/c以外的单个字符 35 // System.out.println(str.length() == 1 && !str.equals("a") && !str.equals("b") && !str.equals("c")); 36 System.out.println(str.matches("[^abc]")); // “ ^ ” 表示 “ 除了 ” 37 38 } 39 40 }
1 package cn.tedu.regex; 2 3 public class PatternDemo2 { 4 5 public static void main(String[] args) { 6 7 String str = "g+3"; 8 9 // 匹配三个字符组成的字符串,第一个字符是一个小写字母,第三个字符是一个数字,中间字符不做限制 10 // . 表示任意字符---通配符----匹配任意一个字符 11 // System.out.println(str.matches("[a-z].[0-9]")); 12 // System.out.println(str.matches("[a-z].\\d")); 13 14 // 如何匹配一个 . 15 // \\. -> \. -> . 16 // System.out.println(str.matches("\\.")); 17 18 // 如何匹配一个 \ ? 19 // C:\Users\Administrator\Desktop\ykb1801\Day13 20 // \\\\ -> \\ -> \ ("\\\"会把“也转义出来) 21 System.out.println(str.matches("\\\\")); 22 23 } 24 25 }
1 package cn.tedu.regex; 2 3 public class PatternDemo3 { 4 5 public static void main(String[] args) { 6 7 String str = "5"; 8 9 // 匹配由a开头后续是数字的字符串 10 // + 表示之前的字符至少出现一次 n >= 1 11 // System.out.println(str.matches("a\\d+")); 12 13 // 匹配数字开头的字符串 14 // * 表示之前的字符可以不出现,也可以出现一次或者多次 n >= 0 15 // System.out.println(str.matches("\\d.*")); 16 17 // 匹配数字开头的最多有两个字符组成的字符串 18 // ? 表示之前的字符最多出现一次 n <= 1 19 System.out.println(str.matches("\\d.?")); 20 } 21 22 }
1 package cn.tedu.regex; 2 3 public class PatternDemo4 { 4 5 public static void main(String[] args) { 6 7 String str = "264258"; 8 9 // 匹配由5个数字组成的的字符串 10 // {n} 表示这个字符出现n次 11 // System.out.println(str.matches("\\d{5}")); 12 13 // 匹配由数字组成的至少长度为5的字符串 14 // {n,} 表示这个字符至少出现n次 15 // System.out.println(str.matches("\\d{5,}")); 16 17 // 匹配由6-12个字符组成的字符串 18 // {m,n} 表示这个字符至少出现m次,但是不超过n次 19 System.out.println(str.matches(".{6,12}")); 20 21 } 22 23 }
1 package cn.tedu.regex; 2 3 public class PatternDemo5 { 4 5 public static void main(String[] args) { 6 7 String str = "二三"; 8 9 // 匹配出现 ab 的字符串 10 // System.out.println(str.contains("ab")); 11 // System.out.println(str.matches(".*ab.*")); 12 13 // 匹配至少出现2次ab的字符串 14 // (字符) --- 捕获组 15 // 正则表达式会对捕获组进行编号,编号是从1开始的 16 // \\n 表示引用编号为n的捕获组 17 System.out.println(str.matches(".*(ab).*\\1.*")); 18 19 // 匹配叠字 哈哈哈 20 // .{2,} 表示匹配至少两个字符组成的字符串 21 // (.)\\1+ -> (.)表示捕获第一个字符,\\1表示引用捕获到的这个字符,+表示这个字符要至少出现一次 22 // System.out.println(str.matches(".{2,}")); 23 // System.out.println(str.matches("(.)\\1+")); 24 25 // ABAB 溜达溜达 26 System.out.println(str.matches("(..)\\1")); 27 28 // AABB 高高兴兴 29 System.out.println(str.matches("(.)\\1(.)\\2")); 30 31 // 捕获组的编号计算是从 ( 第一次出现的位置为准进行计算的 32 // (A((BC)D)E)(F) 33 // \\1 A((BC)D)E 34 // \\2 (BC)D 35 // \\3 BC 36 // \\4 F 37 38 } 39 40 }
1 package cn.tedu.regex; 2 3 public class PatternDemo6 { 4 5 public static void main(String[] args) { 6 7 // String str = "sda33nl5bk+【。成s2d5"; 8 9 // 将字符串中的所有数字替换为+ 10 // System.out.println(str.replaceAll("\\d", "+")); 11 12 // 去掉这个字符串中所有的非数字 13 // System.out.println(str.replaceAll("\\D", "")); 14 15 // String str = "@"; 16 // System.out.println(str.matches("\\@")); 17 18 String str = "Amy Sam Grace Jack Mark "; 19 20 // 交换Sam和Jack的位置 21 System.out.println(str.replaceAll("(Amy )(Sam )(Grace )(Jack )(Mark )", "$1$4$3$2$5")); 22 23 } 24 25 }
1 package cn.tedu.regex; 2 3 import java.util.Arrays; 4 5 public class PatternDemo7 { 6 7 public static void main(String[] args) { 8 9 String str = "87sda3fdg68sa2fd921"; 10 11 // 以数字作为切割符将字符串拆成多个子字符串 12 // 如果多个切割符相邻,这些切割符之前会出现空字符串 --- "" 13 // 切割符只要出现在了末尾,就全部去掉,开头的不切 14 String[] ss = str.split("\\d"); 15 16 System.out.println(Arrays.toString(ss)); 17 18 } 19 20 }
练习:
1. 输入一个字符串,判断这个字符串是否是小数
0.5 00. 5 10.5 10.0 10.00 11.256
1 package cn.tedu.regex; 2 3 import java.util.Scanner; 4 5 public class PatternExer1 { 6 7 public static void main(String[] args) { 8 9 // 获取一个字符串 10 Scanner s = new Scanner(System.in); 11 String num = s.nextLine(); 12 s.close(); 13 14 // 12.9 15 System.out.println(num.matches("0\\.\\d+") || num.matches("[1-9]\\d*\\.\\d+")); 16 17 } 18 19 }
2. 匹配邮箱
数字/字母@数字/字母 . com
qq.com 163.com tedu.cn sina.com.cn
1 package cn.tedu.regex; 2 3 public class PatternExer2 { 4 5 public static void main(String[] args) { 6 7 String email = "langang@tarena.com.cn"; 8 9 System.out.println(email.matches("[a-zA-Z0-9]{5,15}@[a-zA-Z0-9]{1,10}(\\.com)") 10 | email.matches("[a-zA-Z0-9]{5,15}@[a-zA-Z0-9]{1,10}(\\.com)?(\\.cn)")); 11 12 } 13 14 }
3. 匹配密码:6-12位,大写字母/小写字母/数字/空格/_ 至少出现三种
1 package cn.tedu.regex; 2 3 public class PatternExer3 { 4 5 public static void main(String[] args) { 6 7 System.out.println(checkPwd("+AaD2Add1")); 8 9 } 10 11 public static boolean checkPwd(String password) { 12 13 // 长度判断 14 // if(password.length() < 6 || password.length() > 12){ 15 // return false; 16 // } 17 if (!password.matches("[\\w]{6,12}")) { 18 return false; 19 } 20 21 // 定义变量俩记录出现的种类 22 int i = 0; 23 24 // 判断是否含有大写字母 25 if (password.matches(".*[A-Z].*")) { 26 i++; 27 } 28 29 // 判断是否含有小写字母 30 if (password.matches(".*[a-z].*")) { 31 i++; 32 } 33 34 // 判断是否含有数字 35 if (password.matches(".*\\d.*")) { 36 i++; 37 } 38 39 // 判断是否含有空格 40 if (password.matches(".*( ).*")) { 41 i++; 42 } 43 44 // 判断是否含有_ 45 if (password.matches(".*_.*")) { 46 i++; 47 } 48 49 return i >= 3; 50 } 51 52 }
4. 我我我我我爱爱爱爱爱爱爱学学学编编编编编编编程程程程程程 -> 我爱学编程
1 package cn.tedu.regex; 2 3 public class PatternExer5 { 4 5 public static void main(String[] args) { 6 7 String str = "我我我我我爱爱爱爱爱爱爱学学学java"; 8 9 System.out.println(str.replaceAll("(.)\\1+", "$1")); 10 11 } 12 13 }
5. 碎片的平均长度---- xxxyyzxx -> xxx yy z xx -> (3 + 2 + 1 + 2) / 4 = 2---输入一个字符串,获取它的碎片的平均长度
xxxyyz -> xyz
1 package cn.tedu.regex; 2 3 import java.util.Scanner; 4 5 public class PatternExer6 { 6 7 public static void main(String[] args) { 8 9 Scanner s = new Scanner(System.in); 10 String str = s.nextLine(); 11 s.close(); 12 13 // 记录字符串的长度 14 double len = str.length(); 15 16 // 先将字符串中的叠字替换为单字---替换之后碎片的个数不会发生变化 17 str = str.replaceAll("(.)\\1+", "$1"); 18 19 // 替换完之后的字符串的长度就是碎片的个数 20 // 碎片的平均长度 21 System.out.println(len / str.length()); 22 } 23 24 }
6.输入一个字符串,统计里面每个字符出现的次数
1 package cn.tedu.regex; 2 3 import java.util.Scanner; 4 5 public class PatternExer4 { 6 7 public static void main(String[] args) { 8 9 // 获取字符串 10 Scanner s = new Scanner(System.in); 11 String str = s.nextLine(); 12 s.close(); 13 14 // asaadwds 15 16 while (!str.equals("")) { 17 18 // 记录字符串的长度 19 int len = str.length(); 20 21 // 获取这个字符串的首字母 22 char c = str.charAt(0); 23 24 // 将这个字符串中出现的所有的该字符替换掉 25 String regex = String.valueOf(c); 26 if (regex.matches("\\w")) { 27 str = str.replaceAll(regex, ""); 28 } else if (c == '\\') { 29 str = str.replaceAll("\\\\", ""); //解决输入有\的情况 30 } else { 31 str = str.replaceAll("\\" + regex, ""); //解决输入有+的情况 32 } 33 34 35 String str2 = "@"; 36 System.out.println(str2.matches("\\@")); 37 // 长度的变化就是这个字符出现的次数 38 System.out.println(c + ":" + (len - str.length())); 39 40 } 41 } 42 43 }
思考:
1. 输入一个数字,输出前n项的排列形式:
5 -> 1-> 2 1 -> 3 1 2 -> 4 2 1 3 -> 5 3 1 2 4
5 3 1 2 4
6
6 4 2 1 3 5
2. 疯狂值:输入一串数字,然后相邻的两个数字之差的绝对值求和就是这一串数字的疯狂值---求的这串的最大疯狂值
12 45 75 16 85 -> 33 + 30 + 59 + 69 = 194
数学类
Math---最终类,构造函数私有化,针对基本类型提供了初等数学运算---这个类中提供了大量的静态方法来辅助进行数学运算---完全的工具类
BigDecimal---可以用于精确运算,要求参数需要以字符串形式传入
1 package cn.tedu.math; 2 3 public class MathDemo { 4 5 public static void main(String[] args) { 6 7 // 向上取整 8 // System.out.println(Math.ceil(3.2)); 9 10 // 向下取整 11 // System.out.println(Math.floor(3.9)); 12 13 // 四舍五入 14 // System.out.println(Math.round(5.3)); 15 16 // 对任意负数求平方根,结果是NaN 17 // System.out.println(Math.sqrt(-9)); 18 19 // 求a的b次方 20 // System.out.println(Math.pow(2.3, 5.1)); 21 22 // 返回一个介于0-1之间的伪随机小数 0 <= n < 1 23 // System.out.println(Math.random()); 24 25 // 获取30-50之间的随机整数 26 // int i = (int) (Math.random() * 21 + 30); //(0到21+30) 27 // System.out.println(i); 28 29 for (int i = 0; i < 10000; i++) 30 if (Math.random() * Math.random() > 0.95) { 31 System.out.println("亲,恭喜您,中奖啦~~~"); 32 } 33 34 } 35 36 }
1 package cn.tedu.math; 2 3 import java.math.BigDecimal; 4 5 public class BigDecimalDemo { 6 7 // strictfp 修饰方法的,要求方法在计算过程中以80位二进制来计算小数,最后结果赋值给double的时候依然转化为64位 8 public strictfp static void main(String[] args) { 9 10 // 小数在转化为二进制的时候大部分是无法精确表示的 11 // double类型在运算的时候是以64位二进制来运算的 12 double d = 3 - 2.79; 13 System.out.println(d); 14 15 // BigDecimal bd1 = new BigDecimal(3); 16 // BigDecimal bd2 = new BigDecimal(2.79); 17 BigDecimal bd1 = new BigDecimal("3.2"); 18 BigDecimal bd2 = new BigDecimal("2.79"); 19 System.out.println(bd1.subtract(bd2)); 20 21 } 22 23 }
0.20999999999999996
0.21

浙公网安备 33010602011771号