当我开始使用Java时,正则表达式对我来说是一场噩梦。 本教程旨在帮助您掌握Java正则表达式,并让我定期返回以刷新我的正则表达式学习。
什么是正则表达式?
正则表达式定义字符串的模式。 正则表达式可用于搜索,编辑或处理文本。 正则表达式不是特定于语言的,但是每种语言的正则表达式略有不同。 Java正则表达式与Perl最相似。
Java正则表达式类存在于java.util.regex软件包中,该软件包包含三个类: Pattern , Matcher和PatternSyntaxException 。
1.模式对象是正则表达式的编译版本。 它没有任何公共构造函数,我们使用其公共静态方法compile通过传递正则表达式参数来创建模式对象。
2. Matcher是将输入的字符串模式与创建的模式对象进行匹配的正则表达式引擎对象。 此类没有任何公共构造函数,并且我们使用模式对象匹配器方法(将输入String作为参数)来获得Matcher对象。 然后,我们使用matchs方法根据输入的String是否匹配正则表达式模式返回布尔结果。
3.如果正则表达式语法不正确,则会引发PatternSyntaxException。
让我们通过一个简单的示例查看所有这些类的作用:
package com.journaldev.util;import java.util.regex.*;public class PatternExample {public static void main(String[] args) {Pattern pattern = Pattern.compile('.xx.');Matcher matcher = pattern.matcher('MxxY');System.out.println('Input String matches regex - '+matcher.matches());// bad regular expressionpattern = Pattern.compile('*xx*');}}
上面程序的输出是:
Input String matches regex - true
Exception in thread 'main' java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 0
*xx*
^at java.util.regex.Pattern.error(Pattern.java:1924)at java.util.regex.Pattern.sequence(Pattern.java:2090)at java.util.regex.Pattern.expr(Pattern.java:1964)at java.util.regex.Pattern.compile(Pattern.java:1665)at java.util.regex.Pattern.(Pattern.java:1337)at java.util.regex.Pattern.compile(Pattern.java:1022)at com.journaldev.util.PatternExample.main(PatternExample.java:13)
由于正则表达式围绕String展开,因此Java 1.4中对String类进行了扩展,以提供进行模式匹配的match方法。 在内部,它使用Pattern和Matcher类进行处理,但是显然,它减少了代码行。
模式类还包含matches方法,该方法以正则表达式和输入String作为参数,并在匹配它们后返回布尔结果。
因此,以下代码可以很好地将输入String与正则表达式匹配。
String str = 'bbb';System.out.println('Using String matches method: '+str.matches('.bb'));System.out.println('Using Pattern matches method: '+Pattern.matches('.bb', str));
因此,如果您只需要检查输入的String是否与模式匹配,则应使用简单的String Match方法来节省时间。 仅在需要操纵输入String或需要重用模式时,才使用Pattern和Matches类。
请注意,由正则表达式定义的模式从左到右应用于字符串,并且一旦在匹配项中使用了源字符,就无法重用它。
例如,正则表达式“ 121”将匹配“ 31212142121”的次数是“ _121____121”的两倍。
正则表达式常见的匹配符号
正则表达式 | 描述 | 例 |
。 | 匹配任何单个符号,包括所有内容 | (“ ..”,“ a%”)– true(“ ..”,“。a”)– true (“ ..”,“ a”)–否 |
^ xxx | 在行首匹配xxx正则表达式 | (“ ^ ac”,“ abcd”)– true(“ ^ a”,“ a”)– true (“ ^ a”,“ ac”)–否 |
xxx $ | 在行尾匹配正则表达式xxx | (“ .cd $”,“ abcd”)–真(“ a $”,“ a”)–真 (“ a $”,“ aca”)–否 |
[abc] | 可以匹配字母a,b或c。 []被称为字符类。 | (“ ^ [abc] d。”,“ ad9”)–正确(“ [ab] .d $”,“坏”)–正确 (“ [ab] x”,“ cx”)–否 |
[abc] [12] | 可以匹配a,b或c,然后匹配1或2 | (“ [ab] [12]。”,“ a2#”)– true(“ [ab] .. [12]”,“ acd2”)– true (“ [ab] [12]”,“ c2”)–否 |
[^ abc] | 当^是[]中的第一个字符时,它会否定模式,匹配除a,b或c之外的任何其他字符 | (“ [[^ ab] [^ 12]。”,“ c3#”)–真(“ [[^ ab] .. [^ 12]”,“ xcd3”)–真 (“ [^ ab] [^ 12]”,“ c2”)–否 |
[a-e1-8] | 匹配范围从a到e或1到8 | (“ [a-e1-3]”,“ d#”)–真(“ [a-e1-3]”,“ 2”)-真 (“ [a-e1-3]”,“ f2”)–否 |
xx | yy | 匹配正则表达式xx或yy | (“ x。| y”,“ xa”)– true(“ x。| y”,“ y”) (“ x。| y”,“ yz”)–否 |
Java正则表达式元字符
正则表达式 | 描述 |
\ d | 任何数字,少于[0-9] |
\ D | 任何非数字,是[^ 0-9]的缩写 |
\ s | 任何空格字符,是[\ t \ n \ x0B \ f \ r]的缩写 |
\ S | 任何非空白字符,是[^ \ s]的缩写 |
\ w | 任何文字字符,是[a-zA-Z_0-9]的缩写 |
\ W | 任何非单词字符,是[^ \ w]的缩写 |
\ b | 单词边界 |
\ B | 非单词边界 |
在正则表达式中有两种方法可以将元字符用作普通字符。
- 在元字符之前加一个反斜杠(\)。
- 保持元字符在\ Q(以引号开头)和\ E(以引号结尾)之内。
正则表达式量词
量词指定要匹配的字符的出现次数。
正则表达式 | 描述 |
X? | x发生一次或根本不发生 |
X* | X出现零次或多次 |
X + | X发生一次或多次 |
X {n} | X正好发生n次 |
X {n,} | X出现n次或更多次 |
X {n,m} | X发生至少n次但不超过m次 |
量词也可以与字符类和捕获组一起使用。
例如,[abc] +表示a,b或c一次或多次。
(abc)+表示“ abc”组再出现一次。 我们现在将讨论捕获组 。
正则表达式捕获组
捕获组用于将多个字符视为一个单元。 您可以使用()创建一个组。 输入String与捕获组匹配的部分被保存到内存中,可以使用Backreference进行调用。
您可以使用matcher.groupCount方法找出正则表达式模式中的捕获组数。 例如在((a)(bc))中包含3个捕获组; ((a)(bc)),(a)和(bc)。
您可以在正则表达式中使用反引号 (\),然后再调用要调用的组数。
捕获组和反向引用可能会造成混淆,因此让我们通过一个示例来理解它。
System.out.println(Pattern.matches('(\\w\\d)\\1', 'a2a2')); //trueSystem.out.println(Pattern.matches('(\\w\\d)\\1', 'a2b2')); //falseSystem.out.println(Pattern.matches('(AB)(B\\d)\\2\\1', 'ABB2B2AB')); //trueSystem.out.println(Pattern.matches('(AB)(B\\d)\\2\\1', 'ABB2B3AB')); //false
在第一个示例中,在运行时,第一个捕获组是(\ w \ d),当与输入字符串“ a2a2”匹配并保存在内存中时,其计算结果为“ a2”。 因此\ 1指的是“ a2”,因此它返回true。 由于相同的原因,第二条语句打印为false。
尝试自己了解语句3和4的这种情况。
现在,我们将研究一些重要的Pattern和Matcher类方法。
我们可以创建带有标志的Pattern对象。 例如模式。 CASE_INSENSITIVE启用不区分大小写的匹配。
模式类还提供了类似于String类split()方法的split(String) 。
模式类toString()方法返回从中编译此模式的正则表达式String。
Matcher类具有start()和end()索引方法,这些方法精确显示在输入字符串中找到匹配项的位置。
Matcher类还提供String操作方法replaceAll(String替换)和replaceFirst(String替换) 。
现在,我们将通过一个简单的java类看到这些常用功能:
package com.journaldev.util;import java.util.regex.Matcher;
import java.util.regex.Pattern;public class RegexExamples {public static void main(String[] args) {// using pattern with flagsPattern pattern = Pattern.compile('ab', Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher('ABcabdAb');// using Matcher find(), group(), start() and end() methodswhile (matcher.find()) {System.out.println('Found the text \'' + matcher.group()+ '\' starting at ' + matcher.start()+ ' index and ending at index ' + matcher.end());}// using Pattern split() methodpattern = Pattern.compile('\\W');String[] words = pattern.split('one@two#three:four$five');for (String s : words) {System.out.println('Split using Pattern.split(): ' + s);}// using Matcher.replaceFirst() and replaceAll() methodspattern = Pattern.compile('1*2');matcher = pattern.matcher('11234512678');System.out.println('Using replaceAll: ' + matcher.replaceAll('_'));System.out.println('Using replaceFirst: ' + matcher.replaceFirst('_'));}}
上面程序的输出是:
Found the text 'AB' starting at 0 index and ending at index 2
Found the text 'ab' starting at 3 index and ending at index 5
Found the text 'Ab' starting at 6 index and ending at index 8
Split using Pattern.split(): one
Split using Pattern.split(): two
Split using Pattern.split(): three
Split using Pattern.split(): four
Split using Pattern.split(): five
Using replaceAll: _345_678
Using replaceFirst: _34512678
正则表达式是Java面试问题的领域之一,在接下来的几篇文章中,我将提供一些实际示例。
参考: 开发人员食谱博客上的JCG合作伙伴 Pankaj Kumar的Java正则表达式示例教程 。
翻译自: https://www.javacodegeeks.com/2012/11/java-regular-expression-tutorial-with-examples.html