Java - 正则表达式
Java 提供了 java.util.regex 包,用于与正则表达式进行模式匹配。 Java 正则表达式与 Perl 编程语言非常相似,非常容易学习。
正则表达式是一个特殊的字符序列,它使用模式中的特殊语法帮助您匹配或查找其他字符串或字符串集。它们可用于搜索、编辑或操作文本和数据。
java.util.regex 包主要包含以下三个类 -
-
模式类 − 模式对象是正则表达式的编译表示。 Pattern 类不提供公共构造函数。要创建模式,您必须首先调用其中一个公共静态 compile() 方法,然后将返回一个 Pattern 对象。这些方法接受正则表达式作为第一个参数。
-
匹配器类 − Matcher 对象是解释模式并对输入字符串执行匹配操作的引擎。与 Pattern 类一样,Matcher 没有定义公共构造函数。您可以通过调用 matcher() 获得一个 Matcher 对象 Pattern 对象上的方法。
-
模式语法异常 − PatternSyntaxException 对象是一个未经检查的异常,表示正则表达式模式中的语法错误。
捕获组
捕获组是一种将多个字符视为一个单元的方法。它们是通过将要分组的字符放在一组括号内来创建的。例如,正则表达式 (dog) 创建一个包含字母“d”、“o”和“g”的单个组。
捕获组通过从左到右计算它们的左括号来编号。例如,在表达式 ((A)(B(C))) 中,有四个这样的组 -
- ((A)(B(C)))
- (A)
- (B(C))
- (C)
要找出表达式中存在多少组,请在匹配器对象上调用 groupCount 方法。 groupCount 方法返回一个 int 显示匹配器模式中存在的捕获组数。
还有一个特殊的组,组 0,它始终代表整个表达式。该组不包括在 groupCount 报告的总数中。
示例
以下示例说明了如何从给定的字母数字字符串中查找数字字符串 -
现场演示import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches { public static void main( String args[] ) { // String to be scanned to find the pattern. String line = "This order was placed for QT3000! OK?"; String pattern = "(.*)(\\d+)(.*)"; // Create a Pattern object Pattern r = Pattern.compile(pattern); // Now create matcher object. Matcher m = r.matcher(line); if (m.find( )) { System.out.println("Found value: " + m.group(0) ); System.out.println("Found value: " + m.group(1) ); System.out.println("Found value: " + m.group(2) ); }else { System.out.println("NO MATCH"); } } }
这将产生以下结果 -
输出
Found value: This order was placed for QT3000! OK? Found value: This order was placed for QT300 Found value: 0
正则表达式语法
下表列出了 Java 中可用的所有正则表达式元字符语法 -
子表达式 | 匹配项 |
---|---|
^ | 匹配行首。 |
$ | 匹配行尾。 |
. | 匹配除换行符以外的任何单个字符。使用 m 选项也允许它匹配换行符。 |
[...] | 匹配括号中的任何单个字符。 |
[^...] | 匹配任何不在括号中的单个字符。 |
\A | 整个字符串的开头。 |
\z | 整个字符串的结尾。 |
\Z | 整个字符串的结尾,除了允许的最后一行终止符。 |
重新* | 匹配前面表达式的 0 次或多次出现。 |
re+ | 匹配 1 个或多个先前的事物。 |
重新? | 匹配 0 或 1 次出现的前面表达式。 |
重新{ n} | 恰好匹配前面表达式的 n 次出现。 |
re{ n,} | 匹配 n 次或多次出现的前面表达式。 |
re{ n, m} | 匹配至少 n 次和最多 m 次出现的前面表达式。 |
a| b | 匹配 a 或 b。 |
(重新) | 对正则表达式进行分组并记住匹配的文本。 |
(?:re) | 对正则表达式进行分组而不记住匹配的文本。 |
(?> re) | 匹配独立模式而不回溯。 |
\w | 匹配单词字符。 |
\W | 匹配非单词字符。 |
\s | 匹配空格。等价于 [\t\n\r\f]。 |
\S | 匹配非空白。 |
\d | 匹配数字。等价于 [0-9]。 |
\D | 匹配非数字。 |
\A | 匹配字符串的开头。 |
\Z | 匹配字符串的结尾。如果存在换行符,则在换行符之前匹配。 |
\z | 匹配字符串的结尾。 |
\G | 匹配上一次匹配结束的点。 |
\n | 对捕获组编号“n”的反向引用。 |
\b | 匹配括号外的单词边界。匹配括号内的退格 (0x08)。 |
\B | 匹配非单词边界。 |
\n、\t等 | 匹配换行符、回车符、制表符等 |
\Q | 转义(引用)直到 \E 的所有字符。 |
\E | 结束引用以 \Q 开头。 |
Matcher 类的方法
这是有用的实例方法列表 -
索引方法
索引方法提供有用的索引值,精确显示在输入字符串中找到匹配项的位置 -
Sr.No. | 方法和说明 |
---|---|
1 | public int start() 返回上一个匹配的开始索引。 |
2 | public int start(int group) 返回给定组在上一次匹配操作期间捕获的子序列的开始索引。 |
3 | public int end() 返回匹配最后一个字符后的偏移量。 |
4 | public int end(int group) 返回给定组在上一次匹配操作期间捕获的子序列的最后一个字符之后的偏移量。 |
研究方法
研究方法检查输入字符串并返回一个布尔值,指示是否找到模式 -
Sr.No. | 方法和说明 |
---|---|
1 | public booleanlookingAt() 尝试匹配输入序列,从区域的开头开始,与模式匹配。 |
2 | 公共布尔查找() 尝试找到与模式匹配的输入序列的下一个子序列。 |
3 | 公共布尔查找(int start) 重置此匹配器,然后尝试从指定索引处开始查找与模式匹配的输入序列的下一个子序列。 |
4 | 公共布尔匹配() 尝试将整个区域与模式匹配。 |
替换方法
替换方法是替换输入字符串中文本的有用方法 -
Sr.No. | 方法和说明 |
---|---|
1 | public Matcher appendReplacement(StringBuffer sb, String replacement) 实现一个非终端追加和替换步骤。 |
2 | 公共 StringBuffer appendTail(StringBuffer sb) 实现终端追加和替换步骤。 |
3 | public String replaceAll(字符串替换) 用给定的替换字符串替换与模式匹配的输入序列的每个子序列。 |
4 | public String replaceFirst(字符串替换) 用给定的替换字符串替换与模式匹配的输入序列的第一个子序列。 |
5 | 公共静态字符串 quoteReplacement(String s) 返回指定字符串的文字替换字符串。此方法生成一个字符串,该字符串将用作文字替换 s 在 Matcher 类的 appendReplacement 方法中。 |
开始和结束方法
以下是计算单词“cat”在输入字符串中出现的次数的示例 -
示例
现场演示import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches { private static final String REGEX = "\\bcat\\b"; private static final String INPUT = "cat cat cat cattie cat"; public static void main( String args[] ) { Pattern p = Pattern.compile(REGEX); Matcher m = p.matcher(INPUT); // get a matcher object int count = 0; while(m.find()) { count++; System.out.println("Match number "+count); System.out.println("start(): "+m.start()); System.out.println("end(): "+m.end()); } } }
这将产生以下结果 -
输出
Match number 1 start(): 0 end(): 3 Match number 2 start(): 4 end(): 7 Match number 3 start(): 8 end(): 11 Match number 4 start(): 19 end(): 22
您可以看到此示例使用单词边界来确保字母“c”“a”“t”不仅仅是较长单词中的子字符串。它还提供了一些有用的信息,说明在输入字符串中发生匹配的位置。
start 方法返回给定组在上一次匹配操作中捕获的子序列的开始索引,end 返回最后匹配的字符的索引加一。
匹配和查看方法
matches 和 lookingAt 方法都尝试将输入序列与模式进行匹配。但是不同的是,matches 需要匹配整个输入序列,而lookingAt 不需要。
这两种方法总是从输入字符串的开头开始。这是解释功能的示例 -
示例
现场演示import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches { private static final String REGEX = "foo"; private static final String INPUT = "fooooooooooooooooo"; private static Pattern pattern; private static Matcher matcher; public static void main( String args[] ) { pattern = Pattern.compile(REGEX); matcher = pattern.matcher(INPUT); System.out.println("Current REGEX is: "+REGEX); System.out.println("Current INPUT is: "+INPUT); System.out.println("lookingAt(): "+matcher.lookingAt()); System.out.println("matches(): "+matcher.matches()); } }
这将产生以下结果 -
输出
Current REGEX is: foo Current INPUT is: fooooooooooooooooo lookingAt(): true matches(): false
replaceFirst 和 replaceAll 方法
replaceFirst 和 replaceAll 方法替换与给定正则表达式匹配的文本。顾名思义,replaceFirst 替换第一个匹配项,replaceAll 替换所有匹配项。
这是解释功能的示例 -
示例
现场演示import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches { private static String REGEX = "dog"; private static String INPUT = "The dog says meow. " + "All dogs say meow."; private static String REPLACE = "cat"; public static void main(String[] args) { Pattern p = Pattern.compile(REGEX); // get a matcher object Matcher m = p.matcher(INPUT); INPUT = m.replaceAll(REPLACE); System.out.println(INPUT); } }
这将产生以下结果 -
输出
The cat says meow. All cats say meow.
appendReplacement 和 appendTail 方法
Matcher 类还提供了用于文本替换的 appendReplacement 和 appendTail 方法。
这是解释功能的示例 -
示例
现场演示import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches { private static String REGEX = "a*b"; private static String INPUT = "aabfooaabfooabfoob"; private static String REPLACE = "-"; public static void main(String[] args) { Pattern p = Pattern.compile(REGEX); // get a matcher object Matcher m = p.matcher(INPUT); StringBuffer sb = new StringBuffer(); while(m.find()) { m.appendReplacement(sb, REPLACE); } m.appendTail(sb); System.out.println(sb.toString()); } }
这将产生以下结果 -
输出
-foo-foo-foo-
PatternSyntaxException 类方法
PatternSyntaxException 是一个未经检查的异常,它指示正则表达式模式中的语法错误。 PatternSyntaxException 类提供了以下方法来帮助您确定问题所在 -
Sr.No. | 方法和说明 |
---|---|
1 | 公共字符串 getDescription() 检索错误的描述。 |
2 | public int getIndex() 检索错误索引。 |
3 | 公共字符串 getPattern() 检索错误的正则表达式模式。 |
4 | 公共字符串 getMessage() 返回一个多行字符串,其中包含语法错误及其索引的描述、错误的正则表达式模式以及模式内错误索引的可视指示。 |
java