Java正则表达式匹配模式详解

news/2024/12/13 8:54:59/

Java正则匹配的语法,请参考:Pattern (Java Platform SE 8 )

matches和find区别

matches: 输入的字符串必须和正则一摸一样,类似字符串相等的比较方法, "b".equals("b");

find:输入的字符串里面只要包含了正则式表达的内容即可,类似字符串包含的方法, "b".contains("b");

        String word = "my number is 188"; // matches=false, find=trueString word1 = "188999"; // matches=false, find=trueString word2 = "8"; // matches=true, find=truePattern p = Pattern.compile("\\d");Matcher m = p.matcher(word2);System.out.println(m.matches());System.out.println(m.find());

默认匹配案例

       String word = "ac\nab";Pattern p = Pattern.compile("^a.*");Matcher m = p.matcher(word);while (m.find()){System.out.println(m.group());}
//输出
// ac

上面的结果实际上只会输出ac,而ab并不会输出,这是因为Java正则中,如果出现了^ 或 $,默认情况下会忽略任何换行符,也就是说仅仅匹配第一行,后面的所有内容都会被忽略掉,如果我们想要不忽略,就得使用多行匹配模式

如果我们不使用 ^ 和 $ ,那么没问题可以匹配到所有,但如果我们就想在严格的 ^ 和 $ 中进行匹配呢?那么就得使用多行匹配模式了

多行匹配模式MULTILINE

多行匹配模式有两种语法

第一种,使用嵌入表达式:(?m)

       String word = "ac\nab";Pattern p = Pattern.compile("(?m)^a.*"); Matcher m = p.matcher(word);while (m.find()){System.out.println(m.group());}
//输出
// ac
// ab
第二种,指定Flag参数:Pattern.MULTILINE
    String word = "ac\nab";Pattern p = Pattern.compile("^a.*", Pattern.MULTILINE);Matcher m = p.matcher(word);while (m.find()){System.out.println(m.group());}

全字符匹配模式DOTALL

在Java正则语法里面元字符 . 代表除了换行符外的任何字符,但有些时候我们就想匹配有换行符分隔的内容应该怎么做呢?

如果我们使用多行匹配模式,就会发现行不通

在Java里面使用 Pattern.DOTALL 参数 或者 (?s) 嵌入式表达式,代表让 . 代表所有字符,包含换行符
       String word = "run\nhad\noop";
//       Pattern p = Pattern.compile("h.*p", Pattern.DOTALL);Pattern p = Pattern.compile("(?s)h.*p");Matcher m = p.matcher(word);while (m.find()){System.out.println(m.group());}
// 输出
// had
// oop


联合模式匹配 MULTILINE & DOTALL

有时候我们的匹配规则,比较复杂,可能需要联合多种模式一起用:

比如下面的规则:

工作的很好,ok,现在我们需求改为 忽略换行符之后,仅匹配h开头和p结尾的字符串, 我们来分析下:

仅用MULTILINE肯定不行,因为h和p之间隔的有换行符

仅用DOTALL也不行,因为不区分多行,而是把整体当作一个大字符串了

所以只能联合 MULTILINE + DOTALL 两种模式了:

       String word = "run\nhad\noop\nhi\nspx";
//     Pattern p = Pattern.compile("(?ms)^h.*p$"); //嵌入式表达式Pattern p = Pattern.compile("^h.*p$", Pattern.DOTALL | Pattern.MULTILINE);Matcher m = p.matcher(word);while (m.find()){System.out.println(m.group());}
// 输出
// had
// oop

忽略大小写CASE_INSENSITIVE

       String word = "cAt";Pattern p = Pattern.compile("(?i)^h.*p$");
//       Pattern p = Pattern.compile("cat", Pattern.CASE_INSENSITIVE);Matcher m = p.matcher(word);while (m.find()){System.out.println(m.group());}


Linux换行符UNIX_LINES

默认模式中\r\n都会被当做换行符:

       String input= "This is the first line\r"+ "This is the second line\r"+ "This is the third line\r";Pattern p = Pattern.compile("^T.*e");Matcher m = p.matcher(input);while (m.find()){System.out.println("["+m.group()+"]");}
// 输出
// [This is the first line]

当指定了UNIX_LINES后,只会在. ^ $ 中,其他的换行字符都会都会当成一个普通字符

    String input= "This is the first line\r"+ "This is the second line\r"+ "This is the third line\r";Pattern p = Pattern.compile("^T.*e", Pattern.UNIX_LINES);Matcher m = p.matcher(input);while (m.find()){System.out.println("["+m.group()+"]");}
// 输出
// This is the third line]

注意 \r 代表回车,会覆盖之前输出的内容,所以这里看到的结果是最后一段的结果

增加注释COMMENTS

可以在正则中加入解释

       String input= "abc\nbbc";Pattern p = Pattern.compile("a.*c # 寻找以a开头以c结尾的单词", Pattern.COMMENTS);Matcher m = p.matcher(input);while (m.find()){System.out.println("["+m.group()+"]");}

文字解析模式LITERAL

       String input= "abc\nbbc";//仅能与 CASE_INSENSITIVE 和 UNICODE_CASE 搭配Pattern p = Pattern.compile("a.*", Pattern.LITERAL);Matcher m = p.matcher(input);while (m.find()){System.out.println("["+m.group()+"]");}
// 输出为空,所有的元字符会被当成普通字符

非ASCII编码忽略大小写UNICODE_CASE

默认情况下忽略大小写匹配仅支持ASCII编码,如果非ASCII编码需要使用 UNICODE_CASE 和 CASE_INSENSITIVE 组合才有效果

       String input= "À";Pattern p = Pattern.compile("à", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);Matcher m = p.matcher(input);while (m.find()){System.out.println("["+m.group()+"]");}

UNICODE_CHARACTER_CLASS模式

启用此模式,可以使用一些特定匹配规则:

Classes	Matchesb
\p{Lower}	A lowercase character:\p{IsLowercase}
\p{Upper}	An uppercase character:\p{IsUppercase}
\p{ASCII}	All ASCII:[\x00-\x7F]
\p{Alpha}	An alphabetic character:\p{IsAlphabetic}
\p{Digit}	A decimal digit character:p{IsDigit}
\p{Alnum}	An alphanumeric character:[\p{IsAlphabetic}\p{IsDigit}]
\p{Punct}	A punctuation character:p{IsPunctuation}
\p{Graph}	A visible character: [^\p{IsWhite_Space}\p{gc=Cc}\p{gc=Cs}\p{gc=Cn}]
\p{Print}	A printable character: [\p{Graph}\p{Blank}&&[^\p{Cntrl}]]
\p{Blank}	A space or a tab: [\p{IsWhite_Space}&&[^\p{gc=Zl}\p{gc=Zp}\x0a\x0b\x0c\x0d\x85]]
\p{Cntrl}	A control character: \p{gc=Cc}
\p{XDigit}	A hexadecimal digit: [\p{gc=Nd}\p{IsHex_Digit}]
\p{Space}	A whitespace character:\p{IsWhite_Space}
\d	A digit: \p{IsDigit}
\D	A non-digit: [^\d]
\s	A whitespace character: \p{IsWhite_Space}
\S	A non-whitespace character: [^\s]
\w	A word character: [\p{Alpha}\p{gc=Mn}\p{gc=Me}\p{gc=Mc}\p{Digit}\p{gc=Pc}\p{IsJoin_Control}]
\W	A non-word character: [^\w]

这里的匹配使用的unicode下的表示字符,参考:UTS #18: Unicode Regular Expressions

搜索 punctuation 关键词,可以看到unicode下的表示符号,就是我们键盘上非数字非字母部分的符号表示:

       Pattern p = Pattern.compile("\\p{Punct}");Matcher m = p.matcher("`");System.out.println(m.matches()); // returns truePattern p1 = Pattern.compile("\\p{Punct}", Pattern.UNICODE_CHARACTER_CLASS);Matcher m1 = p1.matcher("`");System.out.println(m1.matches()); // returns false

注意上面的第二个不匹配,因为启动了UNICODE_CHARACTER_CLASS,必须用UNICODE_CHARACTER_CLASS下的字符表示才可以匹配

UNICODE的同等关系的CANON_EQ模式

这个一般用在UNICODE的字符中,举个例子:

“◌̇” U+0307 Combining Dot Above Unicode Character

unicode字符U+0307 代表字母上方的一个点 ḃ

而通过 b + \u0307 就能组成 ḃ , 而 ḃ 也有专门的unicode字符表示: \u1E03

也就是说 b\u0307 = \u1E03

在Java的正则里面,如果想要等价表示这个关系,就必须使用CANON_EQ模式匹配才可以

    String regex = "b\u0307";System.out.println(regex);System.out.println("\u1E03");Pattern pattern = Pattern.compile(regex, Pattern.CANON_EQ);Matcher matcher = pattern.matcher("\u1E03");if(matcher.matches()) {System.out.println("Match found");} else {System.out.println("Match not found");}
// 输出
// ḃ
// ḃ
// Match found


http://www.ppmy.cn/news/389603.html

相关文章

索尼爱立信K770i - 更好的方式比其他手机

索尼爱立信K770i - 更好的方式比其他手机   索尼爱立信K770i是一个极好的除了索尼爱立信的的Cyber​​-shot手机交易的产品线。当索尼爱立信K770i是在2008年市场去年二月发布,越来越多的索尼爱立信K770i评论已经出来了,直到今日。索尼爱立信K770i&…

java 国际象棋 中文版_卡尔波夫国际象棋豪华版

快速搜索机型: 诺基亚 N70系列(176208) 7610 3230 6600 6260 6620 6630 6670 6680 6681 6682 N70 N72 ;松下: X700 X800 ;联想: P930 诺基亚 N73系列(240320) N73 5320 5320XM 5320di_XM 5630XM 5700 5700XM 5710XM 5730XM 6110 6110N 6120 6120C 6120ci 6121 6122C 6124C 6210…

索尼爱立信K530c使用简评

原作者:http://www.verydemo.com/demo_c92_i269569.html

索尼爱立信滑盖机java_W580后续机 索尼爱立信滑盖W595官方照发布

第1页:W580顺势接班人 索爱W595官方图赏 第2页:详细规格公布 索爱W595疑点不清 ● 详细规格公布 索爱W595疑点不清 之前曝光的时候,这款W595还支持google map和健身功能,而这次官方发布的资料却没有这两项功能了,不知道是这次发布的资料不全呢…

kotlin协程Job、CoroutineScope作用域,Android

kotlin协程Job、CoroutineScope作用域,Android import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines…

【群智能算法改进】一种改进的白鲸优化算法 改进白鲸优化算法 改进后的EBWO[1]算法【Matlab代码#40】

文章目录 【获取资源请见文章第5节:资源获取】1. 原始BWO算法2. 改进的白鲸优化算法EBWO2.1 Logistic映射2.2 透镜成像折射方向学习 3. 部分代码展示4. 仿真结果展示5. 资源获取 【获取资源请见文章第5节:资源获取】 1. 原始BWO算法 白鲸优化算法 (BWO&…

二分法与差分结合运用(C++)

题目描述 在大学期间,经常需要租借教室。大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室。教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样。 面对海量租借教室的信息,我们自…

(横向刷题)【算法1-6】二分查找与二分答案【算法2-1】前缀和、差分与离散化(上),总结

【算法1-6】二分查找与二分答案 P1024[NOIP2001 提高组] 一元三次方程求解 思路&#xff1a;题目说明根与根之差的绝对值>1,且x1<x2&&f(x1)*f(x2)<0则其中存在解&#xff0c;于是联想到枚举&#xff0c;再用二分答案法控制精度 总结&#xff1a;二分对于精度…