@@ -137,26 +137,6 @@ public class RegexDemo {
137137}
138138```
139139
140- ``` java
141- public static String setHtmlCotentSupportImagePreview(String body) {
142- // 读取用户设置:是否加载文章图片--默认有wifi下始终加载图片
143- if (AppContext . get(AppConfig . KEY_LOAD_IMAGE , true )
144- || TDevice . isWifiOpen()) {
145- // 过滤掉 img标签的width,height属性
146- body = body. replaceAll(" (<img[^>]*?)\\ s+width\\ s*=\\ s*\\ S+" , " $1" );
147- body = body. replaceAll(" (<img[^>]*?)\\ s+height\\ s*=\\ s*\\ S+" , " $1" );
148- // 添加点击图片放大支持
149- // 添加点击图片放大支持
150- body = body. replaceAll(" (<img[^>]+src=\" )(\\ S+)\" " ,
151- " $1$2\" onClick=\" showImagePreview('$2')\" " );
152- } else {
153- // 过滤掉 img标签
154- body = body. replaceAll(" <\\ s*img\\ s+([^>]*)\\ s*>" , " " );
155- }
156- return body;
157- }
158- ```
159-
160140### 1.4 获取功能
161141
162142Pattern和Matcher类的使用
@@ -190,7 +170,7 @@ public class RegexDemo {
190170 }
191171}
192172```
193- - Pattern 匹配模式
173+ ### 1.5 Pattern 匹配模式
194174
195175Pattern类为正则表达式的编译表示形式。指定为字符串的表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建Matcher对象,依照正则表达式,该对象可与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一个模式。
196176
@@ -199,18 +179,115 @@ Pattern类为正则表达式的编译表示形式。指定为字符串的表达
199179| compile() | 把正则表达式编译成匹配模式 |
200180| matcher() | 根据匹配模式去匹配指定的字符串,得到匹配器 |
201181
202- - Matcher 匹配器
182+ ### 1.6 Matcher 匹配器
203183
204- | 方法声明 | 功能描述 |
205- | :-------- | :----------- |
206- | matches() | 匹配字符串 |
207- | find() | 查找有没有满足条件的子串 |
208- | group() | 获取满足条件的子串 |
184+ | 方法声明 | 功能描述 |
185+ | :------------------------ | :--------------------------------------- |
186+ | matches() | 匹配字符串 |
187+ | find() | 查找有没有满足条件的子串 |
188+ | group() | 获取满足条件的子串 |
189+ | reset() | 将Matcher的状态重新设置为最初的状态 |
190+ | reset(CharSequence input) | 重新设置Matcher的状态,并且将候选字符序列设置为input后进行Matcher, 这个方法和重新创建一个Matcher一样,只是这样可以重用以前的对象。 |
191+ | start() | 返回Matcher所匹配的字符串在整个字符串的的开始下标 |
192+ | start(int group) | 指定你感兴趣的sub group,然后返回sup group(子分组)匹配的开始位置。 |
193+ | end() | 返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量。 |
209194
210195- 注意事项
211196
212197Pattern类为正则表达式的编译表示形式。指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建Matcher对象,依照正则表达式,该对象可以与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式
213198
199+ 分组:简单的说,分组其实就是为了能够指定同一个规则可以使用多少次。正则表达式中的分组就是整个大的正则表达式和用()圈起来的内容。
200+
201+ 在这个正则表达式"\\ w(\\ d\\ d)(\\ w+)"中
202+
203+ - 分组0:是"\\ w(\\ d\\ d)(\\ w+)"
204+ - 分组1:是(\\ d\\ d)
205+ - 分组2:是(\\ w+)
206+
207+ 如果我们稍稍变换一下,将原先的正则表达式改为"(\\ w)(\\ d\\ d)(\\ w+)",我们的分组就变成了
208+
209+ - 分组0:是"\\ w(\\ d\\ d)(\\ w+)"
210+ - 分组1:是"(\\ w)"
211+ - 分组2:是"(\\ d\\ d)"
212+ - 分组3:是"(\\ w+)"
213+
214+ 我们看看和正则表达式”\\ w(\\ d\\ d)(\\ w+)”匹配的一个字符串A22happy
215+
216+ - group(0)是匹配整个表达式的字符串的那部分A22happy
217+ - group(1)是第1组(\d\d)匹配的部分:22
218+ - group(2)是第2组(\w+)匹配的那部分happy
219+
220+ ``` java
221+ public static void main(String [] args) {
222+ String Regex = " \\ w(\\ d\\ d)(\\ w+)" ;
223+ String TestStr = " A22happy" ;
224+ Pattern p= Pattern . compile(Regex );
225+ Matcher matcher= p. matcher(TestStr );
226+ if (matcher. find()) {
227+ int gc= matcher. groupCount();
228+ for (int i = 0 ; i <= gc; i++ ) {
229+ System . out. println(" group " + i+ " :" + matcher. group(i));
230+ }
231+ }
232+ }
233+ ```
234+
235+ - start()方法的使用
236+
237+ ``` java
238+ public static void testStart(){
239+ // 创建一个 Matcher ,使用 Matcher.start()方法
240+ String candidateString = " My name is Bond. James Bond." ;
241+ String matchHelper[] = {" ^" ," ^" };
242+ Pattern p = Pattern . compile(" Bond" );
243+ Matcher matcher = p. matcher(candidateString);
244+ // 找到第一个 'Bond'的开始下标
245+ matcher. find();
246+ int startIndex = matcher. start();
247+ System . out. println(candidateString);
248+ System . out. println(matchHelper[0 ] + startIndex);
249+ // 找到第二个'Bond'的开始下标
250+ matcher. find();
251+ int nextIndex = matcher. start();
252+ System . out. println(candidateString);
253+ System . out. println(matchHelper[1 ] + nextIndex);
254+ }
255+ ```
256+
257+ 运行结果:
258+
259+ ![ ] ( img/regex.png )
260+
261+ ``` java
262+ /**
263+ * 测试matcher.group方法
264+ */
265+ public static void testGroup() {
266+ // 创建一个 Pattern
267+ Pattern p = Pattern . compile(" Bond" );
268+ // 创建一个 Matcher ,以便使用 Matcher.group() 方法
269+ String candidateString = " My name is Bond. James Bond." ;
270+ Matcher matcher = p. matcher(candidateString);
271+ // 提取 group
272+ matcher. find();
273+ System . out. println(String . format(" group匹配的字符串 : %s" ,matcher. group()));
274+ System . out. println(String . format(" 匹配的开始位置 : %d" , matcher. start()));
275+ System . out. println(String . format(" 匹配的结束位置 : %d" , matcher. end()));
276+
277+ System . out
278+ .println(" ---再次使用matcher.find()方法,看看matcher中group、start、end方法的效果" );
279+ matcher. find();
280+ System . out. println(String . format(" group匹配的字符串 : %s" ,matcher. group()));;
281+ System . out. println(String . format(" 匹配的开始位置 : %d" , matcher. start()));
282+ System . out. println(String . format(" 匹配的结束位置 : %d" , matcher. end()));
283+ System . out. println(String . format(" candidateString字符串的长度 : %d" , candidateString. length()));
284+ }
285+ ```
286+
287+ 运行结果:
288+
289+ ![ ] ( img/regex1.png )
290+
214291- 获取由三个字符组成的单词
215292
216293``` java
@@ -261,6 +338,64 @@ public class RegexDemo2 {
261338}
262339```
263340
341+ - 判断身份证:要么是15位,要么是18位,最后一位可以为字母,并写程序提出其中的年月日。
342+
343+ ``` java
344+ public static void main(String [] args) {
345+ testID_Card();
346+ }
347+
348+ public static void testID_Card() {
349+ // 测试是否为合法的身份证号码
350+ String [] strs = { " 130681198712092019" , " 13068119871209201x" ,
351+ " 13068119871209201" , " 123456789012345" , " 12345678901234x" ,
352+ " 1234567890123" };
353+ // 准备正则表达式(身份证有15位和18位两种,身份证的最后一位可能是字母)
354+ String regex = " (\\ d{14}\\ w)|\\ d{17}\\ w" ;
355+ // 准备开始匹配,判断所有的输入是否是正确的
356+ Pattern regular = Pattern . compile(regex); // 创建匹配的规则Patter
357+
358+ StringBuilder sb = new StringBuilder ();
359+ // 遍历所有要匹配的字符串
360+ for (int i = 0 ; i < strs. length; i++ ) {
361+
362+ Matcher matcher = regular. matcher(strs[i]);// 创建一个Matcher
363+ sb. append(" 身份证: " );
364+ sb. append(strs[i]);
365+ sb. append(" 匹配:" );
366+ sb. append(matcher. matches());
367+ System . out. println(sb. toString());
368+ sb. delete(0 , sb. length());// 清空StringBuilder的方法
369+ }
370+
371+ GetBirthDay(strs);
372+
373+ }
374+
375+ private static void GetBirthDay(String [] strs) {
376+ System . out. println(" 准备开始获取出生日期" );
377+ // 准备验证规则
378+ Pattern BirthDayRegular = Pattern . compile(" (\\ d{6})(\\ d{8})(.*)" );
379+ // .*连在一起就意味着任意数量的不包含换行的字符
380+ Pattern YearMonthDayRegular = Pattern . compile(" (\\ d{4})(\\ d{2})(\\ d{2})" );
381+ for (int i = 0 ; i < strs. length; i++ ) {
382+ Matcher matcher = BirthDayRegular . matcher(strs[i]);
383+
384+ if (matcher. matches()) {
385+ Matcher matcher2 = YearMonthDayRegular . matcher(matcher. group(2 ));
386+ if (matcher2. matches()) {
387+ System . out. println(strs[i]+ " 中的出生年月分解为: " + " 年" + matcher2. group(1 ) + " 月:" + matcher2. group(2 ) + " 日:" + matcher2. group(3 ));
388+
389+ }
390+ }
391+ }
392+ }
393+ ```
394+
395+ 运行结果:
396+
397+ ![ ] ( img/regex2.png )
398+
264399## 2. 正则表达式工具类
265400
266401``` java
0 commit comments