java正则表达式

一、正则表达式基本规则

  1 package org.mytest;
  2 
  3 
  4 import java.util.Arrays;
  5 //java.util.regex正则表达式工具包
  6 import java.util.Random;
  7 import java.util.regex.Matcher;
  8 import java.util.regex.Pattern;
  9 
 10 
 11 
 12 public class Test {
 13 
 14 
 15     //正则表达式就是字符串, java用regex标识
 16     //字符串的 matches方法可以接收正则表达式
 17     public static void test1() {
 18 
 19         //正则表达式就是字符串
 20         //字符串的 matches方法可以接收正则表达式
 21 //        案例1
 22         //3个字
 23         System.out.println("三个字案例");
 24         String str = "1234";
 25         String str2 = "...";//.在正则表达式的规范就是任意一个字符
 26         System.out.println(str.matches(str2));
 27         System.out.println("123".matches(str2));
 28 
 29 
 30         System.out.println("手机号案例");
 31         //案例2
 32         //判断是否是手机号
 33         //定义字符串匹配规则
 34 //        String pattern = "1[3,5,8]\\d{9}";//[]里面不要乱添加,分割符。错误
 35         String pattern = "1[358]\\d{9}";//正确
 36 //        String pattern = "1[358][1-9]{9}";//另外的正确写法
 37         System.out.println("1,382557144".matches(pattern));//false,如果pattern[]里面有空格就是true
 38         System.out.println("12346578987".matches(pattern));//true
 39 
 40         System.out.println("汉字案例");
 41         //案例3
 42         //判断字符串中有没有汉字
 43         // 以\开始的字符就是转义字符。\u是字符的另一种十六进制写法,是Unicode字符集,可以表示所有世界各国文字 "\u9fa5" 是java的Unicode 转义字符,后面跟4位16进制数,表示一个4位16进制的一个整数
 44         //0x4e00 - 0x9fa5 就是汉字的值的范围。  编码格式 unicode(不要研究)
 45 //        pattern = "[\u4e00-\u9fa5]*";//全是中文吗? 空字符也算。若有字符必须是中文。
 46 //        pattern = ".*[\u4e00-\u9fa5].*";//有中文就行
 47 //        pattern = "[\u4e00-\u9fa5]]{1,}";//全是中文,不能为空
 48         pattern = "[\u4e00-\u9fa5]]+";//全是中文,不能为空
 49 
 50         System.out.println("hello中国!".matches(pattern));
 51         System.out.println("你好".matches(pattern));
 52         System.out.println("".matches(pattern));
 53         //案例4
 54         //要求账号的姓名要么全中文,要么全英文,不能有其它特殊符号
 55         String name = "张三李四王五";
 56         name = name.trim();//清除两边空格
 57 
 58         if(name.matches("[\u4e00-\u9fa5]{2,6}|[a-zA-Z]{2,20}")){//方式1,正则表达式可以有逻辑运算|或者
 59             //还是不要随意添加空格。没有分割符
 60             //作用是:两边的正则表达式满足其一就行
 61             //        if(name.matches("[\u4e00-\u9fa5]{2,6}")||name.matches("[a-zA-Z]{1,20}")){//方式2
 62             System.out.println("命名正确");
 63         }
 64         else{
 65             System.out.println("命名错误");
 66         }
 67 
 68         //总结
 69         //1、不要随意添加分隔字符,每一个字符都是有用的。
 70         //2、 正则表达式有逻辑或运算
 71         //详细规则如下:
 72         System.out.println("单个字符练习案例");
 73 
 74         //非运算
 75         //不是A,
 76         pattern = "[^A]";
 77 //        pattern = "^A";pattern = "^[A]";//^表示开始,正好意义相反了
 78         System.out.println("a".matches(pattern));
 79         System.out.println("A".matches(pattern));
 80         //不是[A-Z]
 81         pattern = "[^A-Z]";
 82         System.out.println("T".matches(pattern));
 83         System.out.println("t".matches(pattern));
 84         //^ -运算符需要写到里面
 85         //^最后运算
 86 
 87         //或者运算符
 88         //a-z或者A-Z
 89         //方式一
 90         pattern  = "[a-zA-Z]";
 91         System.out.println("m".matches(pattern));
 92         System.out.println("M".matches(pattern));
 93         System.out.println("0".matches(pattern));
 94         //方式二
 95         pattern = "[a-z]|[A-Z]";
 96         System.out.println("m".matches(pattern));
 97         System.out.println("M".matches(pattern));
 98         System.out.println("0".matches(pattern));
 99 
100         //java中的转义字符练习
101         //表示空格--java里面 \s就是空格space
102         pattern = "\s";
103 
104         System.out.println(" ".matches(pattern));
105         System.out.println("java中\\s到底是什么:你好啊\s张三");
106         // "\s"就是一个空格的字符串
107 
108 
109         //1、总结正则表达式需要首先遵守java语言的字符串规范。
110                 //1.转义字符会自动转义--java字符串规范
111                 //2.最终的结果遵守正则表达式规范
112                      // 正则表达式也有自己的转义字符,同样用\作为开始
113                 //总而言之,正则表达式要用转义字符,必须写两个\\,一个不够
114         //验证1
115 //        System.out.println("\w");//java中的非法转义符
116         pattern = "\\w";//java中表示字符串 \w  正则表达式中表示表示任意的一位字母或数字
117         System.out.println("1".matches(pattern));//true
118         System.out.println("a".matches(pattern));//true
119         System.out.println("A".matches(pattern));//true
120         System.out.println("".matches(pattern));//false
121 
122         pattern = "\\s";//java中表示字符串 \s 正则表达式该字符串表示一位空格
123         System.out.println(" ".matches(pattern));//true
124         System.out.println("a".matches(pattern));//false
125 
126         //验证2 正则表达式转义字符的大写就是逻辑非
127         System.out.println("z".matches("\\S"));//true
128         System.out.println(" ".matches("\\D"));//true
129 
130         System.out.println("多个字符练习案例");
131         //练习多个字符串
132         //每个字符都是a-z, *就是任意个数的意思
133         pattern = "[a-z]*";
134         //不能为空,+就是至少一个的意思等同于{1,}
135         pattern = "[a-z]+";
136         //0个或1个小写字母
137         pattern = "[a-z]?";
138 //        pattern构造是私有的 ,我们不能new,别人帮我们new
139         //{}表示个数的意思,
140         pattern = "[a-z]{10}";
141         //,分割上下界 相当于+
142         pattern = "[a-z]{1,}";
143         //字符个数闭区间[1,10]
144         pattern = "[a-z]{1,10}";
145 
146         //总结
147         //3.不存在二义性,运行可能出现异常,因为不符合定义规范。
148 
149         //[]{}里面参数不能为空
150         //正则表达式在遵守java字符串规则后,发现不遵守自己的规则,于是出现异常。
151       //异常1  java.util.regex.PatternSyntaxException
152 //        pattern = "[a-z]{}";
153 //        System.out.println("a{}".matches(pattern));
154 
155         //异常2  java.util.regex.PatternSyntaxException
156 //        pattern = "[]";
157 //        System.out.println("[]".matches(pattern));
158         //异常原因:因为若[]里面是空的,[]代表[]里面的任意一个字符,这没有啊,{}里面是空的,个数没法确定了。
159         //异常3  java.util.regex.PatternSyntaxExceptio
160 //        pattern = "\\";
161 //        System.out.println("\\".matches(pattern));
162             //异常原因:符合java字符串语法要求,但是不符合正则表达式语法要求。没法转移啊,类似异常1,和异常2
163 
164 
165         //最后正则表达式的开始和结束标识^和$练习
166 
167         System.out.println("liu".matches("^liu"));//true --自动跳过了开始标识^
168         System.out.println("liu".matches("liu$"));//true --自动跳过了结束标识$
169         System.out.println("liu".matches("^liu$"));//true --自动跳过了开始和结束标识
170         System.out.println("liu".matches("liu"));//true--不添加也可
171         System.out.println();
172         //开始和结束标识说明了是正则表达式,不是普通字符串,这点在java中没有体现。
173         //没有必要,因为java自动认定为正则表达式,正则表达式大部分情况下兼容字符串。
174         // 下面是不兼容的一个情况。
175         //如果开始或结束标识不在相应位置,那么是错误的正则表达式。
176         pattern = "l^i$u";
177         pattern = "^l^i$u$";//我就算加了开始和结束也是不正确的,匹配不到
178 //        pattern = "^l\\^i\\$u$";//这样写,下面的"l^i$u"情况是对的。想要开始和结束出现中间,必须转义
179 
180         System.out.println("i".matches(pattern));//false
181         System.out.println("l^i$u".matches(pattern));//false
182 
183         System.out.println("l".matches(pattern));//false
184         System.out.println("u".matches(pattern));//false
185         System.out.println("li".matches(pattern));//false
186         System.out.println("iu".matches(pattern));//false
187         System.out.println("liu".matches(pattern));//false
188 
189         System.out.println("l^iu".matches(pattern));//false
190         System.out.println("li&u".matches(pattern));//false
191         System.out.println("l^i&u".matches(pattern));//false
192 
193         System.out.println("^liu".matches(pattern));//false
194         System.out.println("liu&".matches(pattern));//false
195         System.out.println("^liu&".matches(pattern));//false
196 
197         System.out.println("^l^i&u&".matches(pattern));//false
198         System.out.println("^l^iu&".matches(pattern));//false
199         System.out.println("^l^i&u&".matches(pattern));//false
200 
201         System.out.println("正则表达式训练结束");
202         System.out.println("使用正则表达式开始:");
203         //案例一
204         //将字符串分割成多个字符串。
205         //"java,php,mysql,javascript,c/c++"可以通过字符串split操作分割成多个字符串数组。
206         String str1 = "java,php,mysql,javascript,c/c++";
207         String[] ch = str1.split(",");
208         System.out.println(Arrays.toString(ch));
209 
210         //那么 "java123php456mysql789javascript567c/c++"怎么分割
211         str1 = "java123php456mysql789javascript567c/c++";//[java, php, mysql, javascript, c/c++]
212 
213 
214         //字符串split方法可以接收正则表达式作为分隔符。
215                 //那么要注意普通字符串和正则表达式不能冲突的问题。这不是我们考虑的,用就行了。
216 
217 //        ch = str1.split("//d+");//低级错误,//不是转义字符
218         ch = str1.split("\\d+");//错误了因为不是转义字符
219 
220         System.out.println(Arrays.toString(ch));//[java, php, mysql, javascript, c/c++]
221 
222         //理解贪婪模式
223         //分组非常妙 -- 反向理解 ->正向理解
224         //换名
225         //找所有的合适的字符串
226         //把他人的项目作者改为自己
227 
228         //什么是贪婪模式--
229         //在字符匹配的时候
230         //我想要  (zhangsan)(java)(lisi)  加括号是为了分组,更加清晰
231 
232         //我这样写正则表达式
233         pattern = ".*java.*";
234         str1 = "zhangsanjavalisi";
235         str2 = "http:127.0.0.0:8080/www.taobao.ui.zhangsanjavalisi.com";
236         System.out.println(str1.matches(pattern));
237         System.out.println(str2.matches(pattern));
238     }
239 
240 
241 
242 
243     public static void main(String[] args){
244         test();
245     }
246 
247     //深入理解正则表达式
248     //java.util.regex包主要包含以下三个类
249     //Pattern类:模式类,
250     //ma 匹配器类
251 
252 
253     public static void test(){
254 
255         Pattern p = Pattern.compile("\\d?");//模式类,返回是一个Pattern
256         //私有的,其它任何人都不能new,类可以new。
257         Matcher m = p.matcher("a");
258         System.out.println(m.matches());//false
259         System.out.println(m.find());//true
260 
261         //把姓李的人的名字列出来
262         String str = """
263                 李四,java
264                 1234王五1234,李武,李留
265                 ,李六七八九sir
266                 """;
267 //        p = Pattern.compile("李.{1,2}");//错误 名字应该是中文
268 //        p = Pattern.compile("李[\u4e00-\u9fa5]*");//错误 性李的名字长度应该2-3
269         p = Pattern.compile("李[\u4e00-\u9fa5]{1,2}");//正确
270 
271         m = p.matcher(str);
272         //输出所有姓李的人 ,类似集合遍历
273         //find()作用
274         // 一方面是看看有没有元素,
275         // 另一方面后移一位元素,方便group()方法使用。
276         //group()作用
277         //返回当前匹配的结果,
278         while(m.find()){
279             System.out.print(m.group()+" ");//输出结果 :李四 李武 李留 李六七
280         }
281         //这个答案,李六七算是半对。可以认为这是名字,也可以认为不是。
282 
283         //1-9要求 按顺序数字顺序写成一个式子
284         // 如 1+23-45+67+8-9
285         // 使得结果为 100
286 
287         //方法1
288         //如果告诉你一个式子,让你计算怎么办
289         str = "1+23-4+56-89";
290         //正解:
291         //使用正则表达式,1.分割整数,2为整数添加符号
292         //使用 Matcher 遍历 拿到所有符合的字符串
293         p = Pattern.compile("-?\\d+");
294 
295         m = p.matcher(str);
296 
297         while (m.find()){
298             System.out.print(m.group()+" ");//1 23 -4 56 -89
299             //这样就有符号了 ,可以将String变为Integer
300         }
301         
302         //剩下问题就是构造,str
303         //Str是随机的,比较简单,但是会重复
304         //Str按照顺序来,
305         // 1-9,正负号
306         Random  random = new Random();
307         //我想着用StringBuilder添加随机的数据
308 //        char[] ch = new char[] {' ','-','+'};//错误 ,只能1位一位的
309         String[] ch = new String[] {"","-","+"};//需要空字符,用于连接两个数字
310 
311         int sum;
312         while(true){
313             sum = 0;
314             //生成一个字符串。
315 //            StringBuilder sb = new StringBuilder();
316             StringBuilder sb = new StringBuilder("1");//需要从1开始
317             for(int i=2; i<=9; i++){
318                 //随机
319 //                sb.append(ch[random.nextInt(3)]);
320 //                sb.append(('0'+i));
321                 sb.append(String.format("%s%d",ch[random.nextInt(3)],i));
322             }
323             //构造输出str
324             str = sb.toString();
325             p = Pattern.compile("-?\\d+");//自动把+去掉了,但是不影响符号
326             m = p.matcher(str);
327             while (m.find()){
328                 sum += Integer.parseInt(m.group());
329             }
330             if(sum==100){
331                 System.out.println(str);
332                 break;
333             }
334         }
335     }
336 }

二、 正则表达式贪婪模式和分组

 1 package before;
 2 //练习贪婪模式
 3 
 4 import java.util.regex.Matcher;
 5 import java.util.regex.Pattern;
 6 
 7 public class Test {
 8     //什么是贪婪模式
 9     //1.在正则表达式字符个数是一定范围时,默认按最多匹配原则,
10     //也就是,如果范围是[1,10]。10个字符匹配的就按10个,10个不匹配,按9个....最后才按1个
11     //这用现象叫做贪婪模式
12     //禁用贪婪
13     //1.在正则表达式字符个数一定范围时,默认按最少匹配原则,
14     public static void test1(){
15         //不贪婪,只有一个,或者最多一个
16         System.out.println("java123mysql6php".replaceAll(".*","-"));
17         //"--"
18         System.out.println("java123mysql6php".replaceAll("","-"));
19         //-j-a-v-a-1-2-3-m-y-s-q-l-6-p-h-p-
20         System.out.println("java123mysql6php".replaceAll(".*?","-"));
21         System.out.println("java123mysql6php".replaceAll("\\d+?","-"));
22         System.out.println("java123mysql6php".replaceAll("\\d","-"));
23         System.out.println("java123mysql6php".replaceAll("\\d{1,}?","-"));
24         //-j-a-v-a-1-2-3-m-y-s-q-l-6-p-h-p-
25         System.out.println("java123mysql6php".replaceAll("\\d+","-"));
26         /*
27 java---mysql-php
28 java---mysql-php
29 java---mysql-php
30 java-mysql-php
31         * */
32     }
33 
34     //案例一:打印出<div>标签有java</div>
35     //易错点,模式匹配
36     //关闭贪婪模式
37     //贪婪模式结论
38     //找到的字符串一定符合Pattern模式要求
39     //1、没有公共部分,不能往回找.
40     //2、符合正则表达式的要求
41     //3、字符串匹配顺序为:从前往后,不论是否关闭贪婪,都是这个顺序,
42     //4、关闭贪婪就是在{1,n}范围尽可能少的找,贪婪模式尽可能多的找
43 
44     public static void test2(){
45         String str = """
46                 <div>hello</div><div> java15 </div><div><p>   java 15</p><span> java8 </p><div>    java 15</div></div>
47                 """;
48         Pattern p = Pattern.compile("(<div>[^<]*?)(java)([^>]*?</div>)");//规定了不选什么
49 //        Pattern p = Pattern.compile("<div>[\\w ]*?java[\\w ]*?</div>");//规定了选哪些值
50         //其它错误
51 //        Pattern p = Pattern.compile("<div>.*?java</div>");
52         //53         //[ ]
54 
55 //        Pattern p = Pattern.compile("<div>(.{0,5}?)(java).*?</div>");//深刻理解控制区间。
56 //        Pattern p = Pattern.compile("<div>(.*?)(java).*?</div>");
57         //结果
58         //<div>hello</div><div>java15</div>
59         //<div><p>java 15</p><span>java8</p><div>java 15</div>
60 //        Pattern p = Pattern.compile("<div>java.*?</div>");
61         //<div>java15</div>
62         //<div>java 15</div>
63 //        Pattern p = Pattern.compile("<div>[\\w ]+?java[\\w ]+?</div>");//{1,} {0,1}有区别
64         //65 //        Pattern p = Pattern.compile("<div>[\\w ]*?(java)[\\w ]*?</div>");//可以添加括号
66         //<div>java15</div>
67         //<div>java 15</div>
68         /*
69          * <div>hello</div><div>java 15</div>
70 <div><p>java 15</p><span>java8</p><div>java 15</div>
71          */
72         Matcher m = p.matcher(str);
73         while(m.find()){
74             System.out.println(m.group());
75         }
76     }
77 
78     //()括号,分组
79     //1.有利于模式匹配;更加清晰.容易理解
80     //2.有利于结果操作;可以批量修改.方便修改,
81     public static void test3(){
82         String str = """
83                 <div>hello</div><div> java15 </div><div><p>   java 15</p><span> java8 </p><div>    java 15</div></div>
84                 """;
85         //只将<div>标签中的java替换为abc
86 
87         Pattern p = Pattern.compile("(<div>[^<]*?)(java)([^>]*?</div>)");
88         Matcher m = p.matcher(str);
89         //替换原来的字符串,返回字符串。
90         String t = m.replaceAll("$1abc$3");
91         System.out.println(t);
92     }
93 
94     public static void main(String[] args) {
95         test2();
96     }
97 }

 1.能用普通字符串解决的不用正则表达式。

 

 

2022/9/17

正则表达式运算符使用

1.字符串startWith不支持正则表达式

12356开头或者 12456开头可以这样写

1 String pattern = "12(3|4)56.*";
2 System.out.println("123565464".matches(pattern));
posted @ 2022-06-13 23:08  liu/564  阅读(237)  评论(0)    收藏  举报