python-learning

正则表达式有什么用?

典型的搜索和替换操作要求您提供与预期的搜索结果匹配的确切文本。虽然这种技术对于对静态文本执行简单搜索和替换任务可能已经足够了,但它缺乏灵活性,若采用这种方法搜索动态文本,即使不是不可能,至少也会变得很困难。通过使用正则表达式,可以

您可能需要搜索整个网站,删除过时的材料,以及替换某些 HTML 格式标记。在这种情况下,可以使用正则表达式来确定在每个文件中是否出现该材料或该 HTML 格式标记。此过程将受影响的文件列表缩小到包含需要删除或更改的材料的那些文件。然后可以使用正则表达式来删除过时的材料。最后,可以使用正则表达式来搜索和替换标记。

实例

正则表达式(Regular Expression)是一种文本模式,包括普通符号(a~z)和特殊字符。

正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。

正则表达式繁琐但强大,学习一种东西只是为了获取某个需求(不然我也不会学)。多数语言都支持利用正则表达式进行字符串操作,由于我有现成的 python 环境,因此这里用 python 为例学习正则表达式。

例如,从字符串中找到数字串

import re

str = 'abc123def'
parttern =  '[0-9]+'
searchObj = re.search(parttern, str)
print(searchObj.group())

简介

Linux 某目录下查找所有 cpp 后缀的文件时,我们会用 ls *.cpp ,这里的 * 就是通配符。 * 通配符匹配零个或多个字符。通过通配符引入正则表达式的学习。如下例子

^[0-9]+abc$

我们在写用户注册表单时,只允许用户名包含字符、数字、下划线和连接符 - ,并设置用户名的长度,我们就可以使用以下正则表达式来设定。

^[a-z0-9_-]{3,15}$

以上正则表达式可以匹配 professordengdeng_shuaideng11 、但是不能匹配 dd,因为太短了。

发展历史

正则表达式原先被用来描述神经网络,后来被发现可以将其应用在计算搜索算法,正则表达式的应用程序包括 Linux 中大名鼎鼎的 vim 编辑器。

现在正则表达式被用到各类开发环境,各种语言,包括 C++、python、vim。

命令或环境 . [] ^ $ \(\) \{\} ? + | ()
vim          
c++          
python

语法

正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某子串中取出符合某个条件的子串等。

构造正则表达式的方法类似创建数学表达式,可以将正则表达式符号进行任意组合形成不同的正则表达式。

正则表达式的符号包括:普通符号(例如 a~z)和特殊符号(元符号)。

普通符号

没有显式指定为元符号的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有有标点符号和一些其他符号

特殊字符

有特殊含义的字符,如上面说的 professo*r 中的 * ,简单的说就是表示任何字符串的意思。如果要查找字符串中的 * 号,则需要对 * 进行转义,即在其前面加上 \ : professo\*r 匹配 professo*r 。也就是说,要匹配特殊字符,首先对特殊字符转义。

特别字符 描述
$ 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 \n\r 。要匹配 $ 字符本身,请使用 \$
() 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \(\)
* 匹配前面的子表达式 0 次或多次。要匹配 * 字符,请使用 \*
+ 匹配前面的子表达式 1 次或多次。要匹配 + 字符,请使用 \+
. 匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \.
[ 标记一个中括号表达式的开始。要匹配 [ ,请使用 \[
? 匹配前面的子表达式 0 次或 1 次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?
\ 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, n 匹配字符 n。\n 匹配换行符。序列 \\ 匹配 \ ,而 \( 匹配 (
^ 匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 \^
{ 标记限定符表达式的开始。要匹配 { ,请使用 \{
| 指明两项之间的一个选择。要匹配 | ,请使用 \|

限定符

限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 *+?{n}{n,}{n,m} 共 6 种。

字符 描述
* 匹配前面的子表达式零次或多次。例如,zo* 匹配 z 以及 zoo* 等价于 {0,}
+ 匹配前面的子表达式零次或多次。例如,zo+ 能匹配 zo 以及 zoo ,但不能匹配 z+ 等价于{1,}
? 匹配前面的子表达式零次或一次。例如,do(es)? 可以匹配 dodoes 以及 doxy 中的 do? 等价于 {0,1}
{n} n 是一个非负整数。匹配确定的 n 次。例如,o{2} 不能匹配 Bob 中的 o ,但是能匹配 food 中的两个 o
{n,} n 是一个非负整数。至少匹配 n 次。例如 o{2,} 不能匹配 Bobo ,但能匹配 foooood 中的所有 oo{1,} 等价于 o+o{0,} 则等价于 o*
{n,m} m 和 n 均为非负整数,其中 n<=m 。最少匹配 n 次且最多匹配 m 次。例如,o{1,3} 将匹配 foooood 中的前三个 oo{0,1} 等价于 o? 。请注意在逗号和两个数之间不能有空格。

由于章节编号在在大的输入文档中很可能超过九,所以您需要一种方式来处理两位或三位章节编号。限定符给您这种能力。下面的正则表达式匹配编号为任何位数的章节标题:

/Chapter [1-9][0-9]*/

参考资料