## 简介

正则表达式是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里，正则表达式通常被用来检索、替换那些匹配某个模式的文本。

## RE模块

在Python中需要通过正则表达式对字符串进行匹配的时候，可以使用一个模块：re

### 语法

```python
# 导入re模块
    import re

    # 使用match方法进行匹配操作
    result = re.match("正则表达式要匹配的字符串")

    # 如果上一步匹配到数据的话，可以使用group方法来提取数据
    result.group()
```

re.match 尝试从字符串的起始位置匹配一个模式，如果不是起始位置匹配成功的话，match()就返回none。

### 正则表达式

#### 单字符匹配

| 字符 | 功能                             |
| :--: | :------------------------------- |
|  .   | 匹配任意1个字符（除了\n）        |
| [ ]  | 匹配[ ]中列举的字符              |
|  \d  | 匹配数字，即0-9                  |
|  \D  | 匹配非数字，即不是数字           |
|  \s  | 匹配空白，即 空格，tab键         |
|  \S  | 匹配非空白                       |
|  \w  | 匹配单词字符，即a-z、A-Z、0-9、_ |
|  \W  | 匹配非单词字符                   |

#### 多个字符匹配

| 字符  | 功能                                                |
| :---: | :-------------------------------------------------- |
|   *   | 匹配前一个字符出现0次或者无限次，即可有可无         |
|   +   | 匹配前一个字符出现1次或者无限次，即至少有1次        |
|   ?   | 匹配前一个字符出现1次或者0次，即要么有1次，要么没有 |
|  {m}  | 匹配前一个字符出现m次                               |
| {m,n} | 匹配前一个字符出现从m到n次                          |

#### 开头结尾匹配

| 字符 | 功能           |
| :--: | :------------- |
|  ^   | 匹配字符串开头 |
|  $   | 匹配字符串结尾 |

#### 分组匹配

|     字符     | 功能                             |
| :----------: | :------------------------------- |
|      \|      | 匹配左右任意一个表达式           |
|     (ab)     | 将括号中字符作为一个分组         |
|    `\num`    | 引用分组num匹配到的字符串        |
| `(?P<name>)` | 分组起别名                       |
|  (?P=name)   | 引用别名为name分组匹配到的字符串 |

### 高级用法

#### search

re.search 扫描整个字符串并返回第一个成功的匹配。

##### 语法

```python
import re

ret = re.search(r"正则表达式", "正则表达式要匹配的字符串")
ret.group()
```

##### match与search的区别

re.match只匹配字符串的开始，如果字符串开始不符合正则表达式，则匹配失败，函数返回None；而re.search匹配整个字符串，直到找到一个匹配。

#### findall

在字符串中找到正则表达式所匹配的所有子串，并返回一个列表，如果没有找到匹配的，则返回空列表。

match 和 search 是匹配一次 findall 匹配所有。


##### 语法

```python
import re

ret = re.findall(r"正则表达式", "正则表达式要匹配的字符串")
print(ret)
```

#### sub

用于替换字符串中的匹配项。

##### 语法

```python
import re

ret = re.sub(r"正则表达式", '替换的字符串', "正则表达式要匹配的字符串")
print(ret)
```

#### split

按照能够匹配的子串将字符串分割后返回列表

##### 语法

```python
import re

ret = re.split(r"正则表达式","正则表达式要匹配的字符串")
print(ret)
```

### 贪婪和非贪婪

Python里数量词默认是贪婪的（在少数语言里也可能是默认非贪婪），总是尝试匹配尽可能多的字符；非贪婪则相反，总是尝试匹配尽可能少的字符。在"*","?","+","{m,n}"后面加上？，使贪婪变成非贪婪。

正则表达式模式中使用到通配字，那它在从左到右的顺序求值时，会尽量“抓取”满足匹配最长字符串，在我们上面的例子里面，“.+”会从字符串的启始处抓取满足模式的最长字符，其中包括我们想得到的第一个整型字段的中的大部分，“\d+”只需一位字符就可以匹配，所以它匹配了数字“4”，而“.+”则匹配了从字符串起始到这个第一位数字4之前的所有字符。

解决方式：非贪婪操作符“？”，这个操作符可以用在"*","+","?"的后面，要求正则匹配的越少越好。

### r的作用

Python中字符串前面加上 r 表示原生字符串，与大多数编程语言相同，正则表达式里使用`\`作为转义字符，这就可能造成反斜杠困扰。假如你需要匹配文本中的字符`\`，那么使用编程语言表示的正则表达式里将需要4个反斜杠`\`：前两个和后两个分别用于在编程语言里转义成反斜杠，转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题，有了原生字符串，你再也不用担心是不是漏写了反斜杠，写出来的表达式也更直观。