Pattern类的作用是在编译正则表达式后创建一个匹配的模式。下面这篇文章主要介绍Java正则表达式的相关信息,比如pattern,通过示例代码非常详细的介绍。有需要的朋友可以参考一下。
目录
模式概述模式匹配模式(模式标志)代码示例多行模式:模式。多行示例忽略case: Pattern。不区分大小写示例启用注释:模式。注释示例启用dotall模式:Pat Tern。DOTALL示例普通字符模式模式:模式。附文字示例:贪婪匹配和懒惰匹配总结
前言
我们按照以下顺序解释这一系列文章:
图案的详细说明;Matcher详解;正则表达式语法的详细解释。
接下来,我们来介绍一下模式类。
在Java中,java.util.regex包定义了正则表达式使用的相关类,其中最重要的两个类是Pattern和Matcher:
编译模式正则表达式以创建匹配模式;Matcher使用模式实例提供的正则表达式来匹配目标字符串,目标字符串是真正影响搜索的对象。
添加另一个新的异常类PatternSyntaxException,它将在遇到非法搜索模式时抛出异常。
Pattern 概述
声明:公共最终类模式实现java.io.serializable
Pattern类是用final修饰的,所以不能被子类继承。
含义:模式类,正则表达式的编译表示。
注意:这个类的实例是不可变的,可以被多个并发线程安全地使用。
Pattern 匹配模式(Pattern flags)
有一个版本的compile()方法,它需要一个参数来控制正则表达式的匹配行为:
Pattern Pattern.compile(字符串正则表达式,int标志)
标志的取值范围
解释模式。UNIX_LINESunix线条模式。大多数系统的行以\n结尾,但是有一些系统,如Windows,以\r\n组合结尾。启用此模式后,只有\n将被用作行终止符,这将影响$和dot (dot匹配换行符)。
通过嵌入的标志表达式(?d)也可以启用Unix线路模式。模式。不区分大小写默认情况下,不区分大小写的匹配仅适用于US-ASCII字符集。此标志允许表达式不区分大小写进行匹配。要匹配大小未知的Unicode字符,只需将UNICODE_CASE与此标志结合使用。
通过嵌入的标志表达式(?I)您还可以启用不区分大小写的匹配。
指定此标志可能会对性能产生一些影响。在这种模式下,匹配时会忽略空格字符(不是表达式中的“//s”,而是表达式中的空格、制表符、回车等)和注释(从#到本行末尾)。
通过嵌入的标志表达式(?x)也可以启用注释模式。模式。MULTILINE默认情况下,将输入字符串视为一行,即使在此行中换行,也视为一行。当" "和" $ "之间的内容匹配时,整个输入被视为一行。当启用多行模式时,包含换行符的输入将自动转换为多行,然后进行匹配。
通过嵌入的标志表达式(?m)也可以启用多线模式。模式。文字启用文字解析模式。
当指定了这个标志时,指定模式的输入字符串将被视为文字字符序列。输入序列中的元字符或转义序列没有特殊含义。
与此标志一起使用时,标志CASE_INSENSITIVE和UNICODE_CASE将影响匹配。其他的标志已经变得多余。
没有可以启用文字解析的嵌入标志字符。模式。DOTALL在这种模式下,表情。可以匹配任何字符,包括行结束符。默认情况下,该表达式不匹配行终止符。
通过嵌入的标志表达式(?s)也可以启用这种模式(s是“单行”模式的助记符,在Perl中也使用)。模式。UNICODE_CASE在此模式下,如果您还启用了CASE_INSENSITIVE标志,它将以不区分大小写的方式匹配UNICODE字符。默认情况下,不区分大小写的匹配仅适用于US-ASCII字符集。
指定此标志可能会影响性能。模式。CANON_EQ当且仅当两个字符的规范分解相同时,才识别出匹配。比如用了这个标志后,表达式a/u030A会匹配?默认情况下,不考虑规范等价。
指定此标志可能会影响性能。
在这些迹象中,模式。不区分大小写,模式。多线和图案。注释是最有用的(其中,模式。注释还可以帮助我们整理思路和/或制作文档。请注意,您可以通过在表达式中插入一个标记来启用大多数模式。这些标记在上面桌子上的标志下面。在你希望模式开始的地方做一个标记。
您可以使用OR (|)运算符来组合这些标志。
代码示例
多行模式:Pattern.MULTILINE 示例
我测试了一下,意思是如果没有多行标志,而$只能匹配输入序列的开头和结尾;否则,您可以在输入序列中匹配行终止符。测试代码如下:
导入Java . util . regex . *;
/**
*多线模式
*/
公共类ReFlags_MULTILINE {
公共静态void main(String[] args) {
//注意里面的换行符
string str=' hello world \ r \ n ' ' hello Java \ r \ n ' ' hello Java ';
system . out . println('==========匹配字符串开头(非多行模式)========');
图案p=pattern.compile('^hello');
matcher m=p . matcher(str);
while (m.find()) {
system . out . println(m . group()' location:[' m . start()',' m . end()']');
}
system . out . println('==========匹配字符串开头(多行模式)========');
p=Pattern.compile('^hello',模式。多线);
m=p . matcher(str);
while (m.find()) {
system . out . println(m . group()' location:[' m . start()',' m . end()']');
}
system . out . println('==========匹配字符串结尾(非多行模式)========');
p=pattern . compile(' Java $ ');
m=p . matcher(str);
while (m.find()) {
system . out . println(m . group()' location:[' m . start()',' m . end()']');
}
system . out . println('==========匹配字符串结尾(多行模式)========');
p=Pattern.compile('java$ ',Pattern。多线);
m=p . matcher(str);
while (m.find()) {
system . out . println(m . group()' location:[' m . start()',' m . end()']');
}
}
}
=========匹配字符串的开头(非多行模式)========
你好位置:[0,5]
=========匹配字符串的开头(多行模式)========
你好位置:[0,5]
你好地点:[13,18]
你好地点:[25,30]
=========匹配字符串的结尾(不是多行模式)==========
Java位置:[31,35]
=========匹配字符串结尾(多行模式)========
Java位置:[19,23]
Java位置:[31,35]
忽略大小写:Pattern.CASE_INSENSITIVE 示例
有时候,需要不分大小写的匹配。在这个例子中,可以匹配摄氏度和华氏度的温度,并且可以匹配所有以C、C、F和F结尾的温度值。
导入Java . util . regex . pattern;
公共类ReFlags_CASE_INSENSITIVE {
公共静态void main(String[] args) {
system . out . println('=========API忽略大小写========');
String moneyRegex='[ -]?(\\d)(。(\\d)*)?(\ \ s)*[CF]';
Pattern p=Pattern . compile(money regex,Pattern。不区分大小写);
system . out . println('-3.33 c ' p . matcher('-3.33 c ')。matches());
system . out . println('-3.33 c ' p . matcher('-3.33 c ')。matches());
System.out.println ('=========忽略大小写=======');
moneyRegex='[ -]?(\\d)(.(\\d)*)?(\ \ s)*[CF]';
p=模式。编译(money regex);
系统。出去。打印匹配器('-3.33摄氏度').matches());
系统。出去。打印匹配器('-3.33摄氏度').matches());
系统。出去。println('===========正则内部忽略大小写===========');
moneyRegex='[ -]?(\\d)(.(\\d)*)?(\\s)*(?I)[CF]';
p=模式。编译(money regex);
系统。出去。打印匹配器('-3.33摄氏度').matches());
系统。出去。打印匹配器('-3.33摄氏度').matches());
系统。出去。println('===========内部不忽略大小写===========');
moneyRegex='[ -]?(\\d)(.(\\d)*)?(\ \ s)*[CF]';
p=模式。编译(money regex);
系统。出去。打印匹配器('-3.33摄氏度').matches());
系统。出去。打印匹配器('-3.33摄氏度').matches());
}
}
===========API忽略大小写===========
-3.33c真
-3.33C真
===========不忽略大小写===========
-3.33c假
-3.33C真
===========正则内部忽略大小写===========
-3.33c真
-3.33C真
===========内部不忽略大小写===========
-3.33c假
-3.33C真
启用注释:Pattern.COMMENTS 示例
启用注释,开启之后,正则表达式中的空格以及#号行将被忽略。
导入Java。util。正则表达式。图案;
公共类ReFlags_COMMENTS {
公共静态void main(String[] args) {
系统。出去。println('===========API启用注释===========');
字符串注释='(\ \ d)#这是注释。';
模式p=模式.编译(注释,模式。评论);
系统。出去。println(' 1234 '页匹配器(' 1234 ').matches());
系统。出去。println('===========不启用注释===========');
comments='(\ \ d)#这是注释。';
p=模式.编译(注释);
系统。出去。println(' 1234 '页匹配器(' 1234 ').matches());
系统。出去。println('===========正则启用注释===========');
评论='(?x)(\ \ d)#这是注释。';
p=模式.编译(注释);
系统。出去。println(' 1234 '页匹配器(' 1234 ').matches());
系统。出去。println('===========不启用注释===========');
comments='(\ \ d)#这是注释。';
p=模式.编译(注释);
系统。出去。println(' 1234 '页匹配器(' 1234 ').matches());
}
}
===========API启用注释===========
1234真
===========不启用注释===========
1234假
===========正则启用注释===========
1234真
===========不启用注释===========
1234假
可以看到,#号到行尾的注释部分和前面的空白字符都被忽略了。正则表达式内置的启用注释为(?x)。
启用 dotall 模式:Pattern.DOTALL 示例
启用dotall模式,一般情况下,点号(.)匹配任意字符,但不匹配换行符,启用这个模式之后,点号还能匹配换行符。
导入Java。util。正则表达式。图案;
公共类ReFlags_DOTALL {
公共静态void main(String[] args) {
系统。出去。println('===========API启用DOTALL===========');
String dotall='xml .)*/XML ';
模式p=模式。编译(dotall,Pattern .DOTALL);
系统。出去。println(' XML \ \ r \ \ n/XML ' p . matcher(' XML \ r \ n/XML ').matches());
系统。出去。println('===========不启用DOTALL===========');
dotall='xml(.)*/XML ';
p=模式。编译(dotall);
系统。出去。println(' XML \ \ r \ \ n/XML ' p . matcher(' XML \ r \ n/XML ').matches());
系统。出去。println('===========正则启用DOTALL===========');
dotall='(?s)xml(.)*/XML ';
p=模式。编译(dotall);
系统。出去。println(' XML \ \ r \ \ n/XML ' p . matcher(' XML \ r \ n/XML ').matches());
系统。出去。println('===========不启用DOTALL===========');
dotall='xml(.)*/XML ';
p=模式。编译(dotall);
系统。出去。println(' XML \ \ r \ \ n/XML ' p . matcher(' XML \ r \ n/XML ').matches());
}
}
===========API启用DOTALL============
xml\r\n/xml true
===========不启用DOTALL============
xml\r\n/xml false
=========常规启用dotall==========
xml\r\n/xml true
=========不启用dotall==========
xml\r\n/xml false
平白字符模式 模式:Pattern.LITERAL 示例
启用此模式后,所有元字符和转义字符都被视为普通字符,没有其他含义。
导入Java . util . regex . pattern;
公共类ReFlags_LITERAL {
公共静态void main(String[] args) {
system . out . println(Pattern . compile(' \ \ d ',Pattern。文字)。匹配器(' \\d ')。matches());//真
system . out . println(Pattern . compile(' \ \ d ',Pattern。文字)。匹配器(' 2 ')。matches());//假
system . out . println(Pattern . compile('(\ \ d))、Pattern。文字)。匹配器(' 1234 ')。matches());//假
system . out . println(pattern . compile('(\ \ d)')。匹配器(' 1234 ')。matches());//真
system . out . println(Pattern . compile('(\ \ d){ 2,3} ',Pattern。文字)。匹配器('(\\d){2,3} ')。matches());//真
}
}
附:贪婪匹配与懒惰匹配
考虑这个表达式:a.*b,它将匹配以A开头以b结尾的最长字符串,如果用它来搜索aabab,它将匹配整个字符串aabab。这就是所谓的贪婪匹配。
有时候,我们更需要懒匹配,也就是匹配尽可能少的字符。前面的限定词都可以转换成懒人匹配模式,后面加个问号就行了?这边走。*?意思是匹配任意次数的重复,但是在整个匹配能够成功的前提下使用最少的重复。
a.*?b匹配最短的字符串,以A开头,以b结尾,如果应用于aabab,将匹配aab和ab。
公共静态void main(String[] args) {
String='北京(海淀区)(朝阳区)';
字符串paternStr='。*(?=\\()';
pattern pattern=pattern . compile(patern str);
matcher matcher=pattern . matcher(str);
if (matcher.find()) {
system . out . println(matcher . group(0));
}
}
上述方法的输出是:北京(海淀区)
公共静态void main(String[] args) {
String='北京(海淀区)(朝阳区)';
字符串paternStr='。*?(?=\\()';
pattern pattern=pattern . compile(patern str);
matcher matcher=pattern . matcher(str);
if (matcher.find()) {
system . out . println(matcher . group(0));
}
}
上述方法的输出:北京
总结
这就是这篇关于Java正则表达式模式的文章。有关Java正则表达式模式的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望你以后能支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。