# Java 正则表达式教程

> 原文： [https://howtodoinjava.com/java-regular-expression-tutorials/](https://howtodoinjava.com/java-regular-expression-tutorials/)

**正则表达式**用作字符串的**搜索模式**。 使用正则表达式，我们也可以找到一个或多个匹配项。 我们可以在字符串中查找匹配的任何国王，例如简单字符，固定字符串或任何复杂的字符模式，例如电子邮件，SSN 或域名。

## 1\. 正则表达式

正则表达式是强大，灵活和高效的文本处理的关键。 它允许您描述和解析文本。 正则表达式可以添加，删除，隔离和折叠，纺锤并破坏各种文本和数据。

#### 1.1 元字符和字面值

完整的正则表达式由两种类型的字符组成。

*   *特殊字符*（类似于文件名中的`*`）称为**元字符**。
*   其余的称为**字面值**或*普通文本字符*。

正则表达式从其元字符提供的高级表达能力中受益。 我们可以将文本视为字面值，将元字符视为语法。 根据一组规则将单词与语法结合在一起，以创建表达思想的表达。

#### 1.2 Java 正则表达式示例

让我们看一个使用正则表达式作为参考的 Java 快速示例。

```java
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main 
{
 public static void main(String[] args) 
 {
  Pattern pattern = Pattern.compile("Alex|Brian");
  Matcher matcher = pattern.matcher("Generally, Alex and Brian share a great bonding.");

  while (matcher.find()) {
            System.out.print("Start index: " + matcher.start());
            System.out.print(" End index: " + matcher.end() + " ");
            System.out.println(" - " + matcher.group());
        }
 }
}

```

程序输出。

```java
Start index: 11 End index: 15  - Alex
Start index: 20 End index: 25  - Brian

```

## 2\. 正则表达式元字符

让我们探索常用的元字符以更好地理解它们。

#### 2.1 行的起点和终点

起点和终点分别用`'^'`（脱字符）和`'$'`（美元）符号表示。 插入号和美元的特殊之处在于它们**与行**中的位置匹配，而不是与任何实际的文本字符本身匹配。

例如，正则表达式“`cat`”在字符串中的任何位置都可以找到“`cat`”，但是仅当“`cat`”位于行首时，“`^cat`”才匹配。 例如诸如“`category`”或“`catalog`”之类的词。

同样，“`cat$`”仅在“`cat`”位于行尾时匹配。 例如像“`scat`”之类的词。

#### 2.2 字符类

通常称为字符类的正则表达式构造`"[···]"`让我们列出了比赛中该点要允许的字符。 字符类在创建拼写检查器时很有用。

例如，“`e`”仅与`e`匹配，而“`a`”仅与`a`匹配，而正则表达式`[ea]`则与之匹配。 例如`sep[ea]r[ea]te`将匹配所有单词“`separate`”，“`separate`”和“`separete`”。

另一个示例可以是允许将单词的第一个字母大写，例如`[Ss]mith`将同时允许使用`smith`和`Smith`这两个字。

同样，`<[hH][123456]>`将匹配所有标题标签，即`H1`，`H2`，`H3`，`H4`，`H5`和`H6`。

###### 2.2.1 字符范围

破折号`"-"`表示字符范围。 `<[hH][1-6]>`与`<[hH][123456]>`相似。 其他有用的字符范围是`[0-9]`和`[a-z]`，它们匹配数字和英文小写字母。

我们可以在单个结构中指定多个范围 `[0123456789abcdefABCDEF]`可以写为`[0-9a-fA-F]`。 请注意，给出范围的顺序无关紧要。

请注意，破折号仅是字符类中的元字符，否则它与常规破折号匹配。 另外，如果它是范围中列出的第一个字符，则它不可能表示范围，因此在这种情况下将不是元字符。

###### 2.2.2 否定字符类

如果我们在字符类中使用否定符号`^`，则该类与**未列出的任何字符匹配**。 例如 `[^1-6]`匹配的字符不是 1 到 6。

#### 2.3 将任何字符与点匹配

元字符`.`是与任何字符匹配的字符类的简写。 请注意，在字符类中使用点时，它们不是元字符。 在字符类中，它只是一个简单的字符。

例如，`06.24.2019`将匹配`06/24/2019`或`06-24-2019`或`06.24.2019`。 但是
`06[.]24[.]2019`仅与`06.24.2019`匹配。

#### 2.4 匹配交替 - 几个子表达式中的任何一个

管道符号`'|'`允许您将多个表达式组合成一个与任何单个表达式匹配的表达式。

例如，“`Alex`”和“`Brian`”是单独的表达式，但是`Alex|Brian`是一个与两者都匹配的表达式。

与点类似，在字符类中使用管道时，管道也不是元字符。 在字符类中，它只是一个简单的字符。

例如，要匹配单词“`First`”或“`1st`”，我们可以编写正则表达式 – “`(First|1st)`”或简写为`"(Fir|1)st"`。

## 3\. Java 正则表达式 API

Java 具有内置的 API（`java.util.regex`）以使用正则表达式。 我们不需要任何第三方库就可以对 Java 中的任何字符串运行正则表达式。

Java 正则表达式 API 提供 1 个接口和 3 个类：

*   **`Pattern`** – 必须将指定为字符串的正则表达式首先编译为此类的实例。 然后，可以使用所得的模式来创建`Matcher`对象，该对象可以将任意字符序列与正则表达式进行匹配。

    ```java
    Pattern p = Pattern.compile("abc");
    Matcher m = p.matcher("abcabcabcd");
    boolean b = m.matches(); //true

    ```

*   **`Matcher`** – 此类提供执行匹配操作的方法。
*   **`MatchResult`（接口）** – 这是匹配操作的结果。 它包含用于确定与正则表达式匹配的结果的查询方法。
*   **`PatternSyntaxException`** – 引发非受检的异常，表示正则表达式模式中的语法错误。

详细了解这些类和重要方法。

#### 3.1 `Pattern`类

它表示正则表达式的编译表示。 要使用 Java 正则表达式 API，我们必须将正则表达式编译为此类。

编译后，其实例可用于创建`Matcher`对象，该对象可以将行/字符串与正则表达式匹配。

请注意，许多匹配器可以共享同一模式。 处理期间的状态信息保存在`Matcher`实例中。

此类的实例为[**不可变的**](https://howtodoinjava.com/java/basics/how-to-make-a-java-class-immutable/)，可以安全地由多个并发线程使用。

*   **`Predicate asPredicate()`** - 创建可用于匹配字符串的 [Java 8 谓词](https://howtodoinjava.com/java8/how-to-use-predicate-in-java-8/)。
*   **`static Pattern compile(String regex)`** – 用于将给定的正则表达式编译为模式。
*   **`static Pattern compile(String regex, int flags)`** – 用于将给定的正则表达式编译为带有给定标志的模式。
*   **`int flags()`** - 用于返回此模式的匹配标志。
*   **`Matcher matcher(CharSequence input)`** – 用于创建匹配器，该匹配器将根据该模式匹配给定的输入。
*   **`static boolean match(String regex, CharSequence input)`** – 用于编译给定的正则表达式，并尝试将给定的输入与其匹配。
*   **`String.pattern()`** – 用于返回从中编译此模式的正则表达式。
*   **`static String quote(String s)`** – 用于返回指定字符串的字面模式串。
*   **`String[] split(CharSequence input)`** – 用于在此模式的匹配项附近拆分给定的输入序列。
*   **`String[] split(CharSequence input, int limit)`** – 用于在此模式的匹配项附近分割给定的输入序列。
*   **`Stream splitAsStream(CharSequence input)`** – 根据该模式的匹配从给定的输入序列创建[流](https://howtodoinjava.com/java8/java-streams-by-examples/)。

#### 3.2 `Matcher`类

它是通过解释`Pattern`在字符串/行上执行匹配操作的主要类。 创建匹配器后，可将其用于执行各种匹配操作。

此类还定义了用新字符串替换匹配子序列的方法，如果需要，可以根据匹配结果计算其内容。

此类的实例是**不是[线程安全的](https://howtodoinjava.com/java/multi-threading/what-is-thread-safety/)**。

*   **`boolean find()`** – 主要用于搜索文本中多个出现的正则表达式。
*   **`boolean find(int start)`** – 用于从给定索引开始搜索文本中正则表达式的出现。
*   **`int start()`** – 用于获取使用`find()`方法找到的匹配项的开始索引。
*   **`int end()`** – 用于获取使用`find()`方法找到的匹配项的结束索引。 它返回最后一个匹配字符旁边的字符索引。
*   **`int groupCount()`** – 用于查找匹配的子序列的总数。
*   **`String.group()`** – 用于查找匹配的子序列。
*   **`boolean matchs()`** – 用于测试正则表达式是否与模式匹配。
*   **`boolean lookingAt()`** – 尝试从区域的开头开始，将模式与输入序列进行匹配。
*   **`String quoteReplacement(String s)`** – 返回指定字符串的字面替换字符串。
*   **`Matcher reset()`** – 重置此匹配器。
*   **`MatchResult toMatchResult()`** – 以`MatchResult`的形式返回此匹配器的匹配状态。

## 4\. Java 正则表达式示例

阅读下面给出的示例，以了解正则表达式在解决应用程序中这些特定问题方面的用法。

#### 电子邮件地址的正则表达式

学习使用 Java 中的正则表达式匹配电子邮件地址

```java
^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$
```

#### 用于密码验证的正则表达式

学习使用 Java 中的正则表达式匹配密码

```java
((?=.*[a-z])(?=.*d)(?=.*[@#$%])(?=.*[A-Z]).{6,16})
```

#### 商标符号的正则表达式

学习使用 Java 中的正则表达式匹配商标符号

```java
\u2122
```

#### 任何货币符号的正则表达式

学习使用 Java 中的正则表达式匹配货币符号

```java
\\p{Sc}
```

#### “希腊扩展”或希腊语脚本中任何字符的正则表达式

使用 Java 中的正则表达式学习在希腊扩展和希腊脚本中匹配字符

```java
\\p{InGreek} and \\p{InGreekExtended}
```

#### 北美电话号码的正则表达式

学习使用 Java 中的正则表达式匹配北美电话号码

```java
^\\(?([0-9]{3})\\)?[-.\\s]?([0-9]{3})[-.\\s]?([0-9]{4})$
```

#### 国际电话号码的正则表达式

学习使用 Java 中的正则表达式匹配国际电话号码

```java
^\+(?:[0-9] ?){6,14}[0-9]$
```

#### 日期格式的正则表达式

学习使用 Java 中的正则表达式匹配日期格式

```java
^[0-3]?[0-9]/[0-3]?[0-9]/(?:[0-9]{2})?[0-9]{2}$
```

#### 社会安全号码（SSN）的正则表达式

学习使用 Java 中的正则表达式匹配 SSN

```java
^(?!000|666)[0-8][0-9]{2}-(?!00)[0-9]{2}-(?!0000)[0-9]{4}$
```

#### 国际标准书号（ISBN）的正则表达式

学习使用 Java 中的正则表达式匹配 ISBN

```java
^(?:ISBN(?:-1[03])?:? )?(?=[0-9X]{10}$|(?=(?:[0-9]+[- ]){3})
[- 0-9X]{13}$|97[89][0-9]{10}$|(?=(?:[0-9]+[- ]){4})[- 0-9]{17}$)
(?:97[89][- ]?)?[0-9]{1,5}[- ]?[0-9]+[- ]?[0-9]+[- ]?[0-9X]$
```

#### 美国邮政编码的正则表达式

学习使用 Java 中的正则表达式匹配美国邮政编码

```java
^[0-9]{5}(?:-[0-9]{4})?$
```

#### 加拿大邮政编码的正则表达式

学习使用 Java 中的正则表达式匹配加拿大邮政编码

```java
^(?!.*[DFIOQU])[A-VXY][0-9][A-Z] ?[0-9][A-Z][0-9]$
```

#### 英国邮政编码（邮政编码）的正则表达式

学习使用 Java 中的正则表达式匹配英国邮政编码

```java
^[A-Z]{1,2}[0-9R][0-9A-Z]? [0-9][ABD-HJLNP-UW-Z]{2}$
```

#### 信用卡号码的正则表达式

学习使用 Java 中的正则表达式匹配信用卡号

```java
^(?:(?4[0-9]{12}(?:[0-9]{3})?)|
		(?5[1-5][0-9]{14})|
		(?6(?:011|5[0-9]{2})[0-9]{12})|
		(?3[47][0-9]{13})|
		(?3(?:0[0-5]|[68][0-9])?[0-9]{11})|
		(?(?:2131|1800|35[0-9]{3})[0-9]{11}))$
```

#### 更多正则表达式示例

[匹配字符串的开头或结尾（行锚）](https://howtodoinjava.com/regex/start-end-of-string/)

[匹配任何字符或字符集](https://howtodoinjava.com/regex/match-any-set-of-characters/)

请在注释中向我发送与此 **java 正则表达式教程**有关的问题。

学习愉快！

参考文献：

[`java.util.regex`包](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/regex/package-summary.html)