,,Java正则表达式之Pattern类实例详解

,,Java正则表达式之Pattern类实例详解

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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: