正则表达式

正则表达式

之前在爱立信实习的时候就接触到了正则表达式,学Python也学了正则表达式,自己也写了一篇博客介绍正则表达式。 http://www.cnblogs.com/hai-persist/p/3514027.html 。现在觉得还有很多需要学习的。
今天学习文本处理命令grep命令,又接触到了正则表达式,然而Linux的正则表达式又将其进行分类了,分成基本正则表达式和扩展正则表达式。不过说实话,我们更多就使用扩展正则表达式就行了(如grep,就直接用grep -E就能够用扩展正则表达式了),但这里也要进行一下比较。主要有:

  1. 基本正则表达式;
  2. 扩展正则表达式;
  3. Python正则表达式;
  4. Perl正则表达式。

扩展表达式相对于基本正则表达式额优势主要是有一些特殊字符不需要再进行转义,如 {}等。

由于我目前主要用Python,因此我就对比了前三类。

字符 字符说明 基本正则表达式 扩展正则表达式 Python正则表达式
\ 转义字符 \ \ \
^ 匹配行首 ^ ^ ^
$ 匹配行结尾 $ $ $
^$ 匹配空行 ^$ ^$ ^$
^string$ 匹配string行 ^string$ ^string$ ^string$
\< 匹配单词开始 \< \< 不支持这种用法,但可用\b \bthe
> 匹配单词结尾 > > 不支持,但可用the\b
\< > 匹配单词 \< > \< > 不支持,可用\b...\b
? 匹配前面0次或1次 ? ? ?
. 匹配除换行符('\n')之外的任意单个字符 . (如果要匹配包括“\n”在内的任何一个字符,请使用:'(^$)|(.) .
匹配前面字符0次或N次
+ 匹配前面字符至少1次以上 不支持 + +
+ 匹配前面字符至少1次以上 + 不支持 不支持
{n} 匹配前面字符n次 不支持,必须加转义字符。{n} {n} {n}
{n,} 至少n次, 不支持。{n,} {n,} {n,}
{n,m} N次到m次 不支持{n,m} {n,m} {n,m
A | B 匹配A或者B 不支持 A |B A|B
\d 匹配数字 不支持(用[0-9]或者[[:digit:]] 不支持 \d
\D 非数字字符 不支持 不支持 \D
\s 匹配空白字符 不支持 不支持 \s
\S 匹配非空白 不支持 不支持 \S
\w 匹配字符 \w \w \w
\b 匹配便捷 \b \b \b
\r 匹配回车符 不支持 不支持 \r
\n 匹配换行符 不支持 不支持 \n
() 匹配组表达式 不支持该用法 () ()


上面比较了几种正则表达式的不同,同时也把涉及到的一些正则表达式的方法写了出来。在实际应用中主要是对这些方法的综合应用,主要是要注意几个特殊符号:
1. 反义字符组。 [^xy] 意思是不匹配xy;
2. () 括号里的是一组,就是可以不止一个字符。如 (ab)+,即匹配含有一对以上的ab。
3. | 相当于编程语言的逻辑 或,匹配任意一个都行。
4. [xyz] 意思是匹配方括号里的任意一个字符。
5. {n},{n,},{n,m},说明的是匹配n次,n次或以上。n到m次。


具体例子:

1、匹配国内固定电话号码。

分析:

  • 固定电话由区号和号码组成;
  • 组成格式有三种:xxx-xxxxx,xxxyyyyyy,(xxx)xxxxx;
  • 区号可以是三位,也可以是4位;
  • 号码是固定8位;
  • 区号第一位都是0.

表达式:
1. 首先是区号 xxx- ,xxx , (xxx) :(?0\d{2,3}[)-]?;
2. 其次是号码,比较简单,固定8位。\d{8}.
(?0\d{2,3}[)-]?\d{8}

2、匹配邮箱。

分析:
- 邮箱@前面的格式可以是单个字符串,也可以是用连接符_,-连接的字符串,xxx,xxx_xxx,xxx-xxx;
- @后面的一般为xxx.xx,xxx.xxx.xx;

表达式:
1.邮箱@前面: xxx_,xxx-是可以没有的。 ^[a-zA-Z0-9]+(-_)?[a-zA-Z0-9]+
2.邮箱@后面:

  • 首先最后面的最好确定,2到3个字符 \w{2,3}$ ;
  • 前面的点号可以出现1次或者2次。将每个点号和前面的字符当做一个单元,即每个单元出现1到2次。(单元){1,2};
  • 单元的内容可以为 xxx_xxx.,xxx.,xxx-xxx.因此: [a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+.

邮箱后面: ([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+.){1,2}\w{2,3}$

邮箱验证: [a-zA-Z0-9]+[- ]?[a-zA-Z0-9]+@([a-zA-Z0-9]*[- ]?[a-zA-Z0-9]+.){1,2}\w{2,3}$


python的re模块应用

通过调用dir函数,查询re属性,如下是re模块含有的所有属性

['DEBUG', 'DOTALL', 'I', 'IGNORECASE', 'L', 'LOCALE', 'M', 'MULTILINE', 'S', 'Scanner', 'T', 'TEMPLATE', 'U', 'UNICODE', 'VERBOSE', 'X', '_MAXCACHE', ' all ', ' builtins ', ' doc ', ' file ', ' name ', ' package ', ' version ', '_alphanum', '_cache', '_cache_repl', '_compile', '_compile_repl', '_expand', '_pattern_type', '_pickle', '_subx', 'compile', 'copy_reg', 'error', 'escape', 'findall', 'finditer', 'match', 'purge', 'search', 'split', 'sre_compile', 'sre_parse', 'sub', 'subn', 'sys', 'template']

compile

预编译正则表达式规则,以便后续使用该正则表达式方便,会返回一个正则对象,regex.

eg:prog = re.compile(pattern) pattern 是你自己定义的正则表达式

search ,match,findall

之所以把他们一起讨论,是因为有相同点,也有不同点。

相同点都是搜索字符根据特定的正则表达式进行匹配;

不同点:

  • match只是匹配字符串的开头,如果不匹配,就退出,返回一个None。

  • search可以匹配字符串的任意位置,如果整个字符串都不匹配,返回一个None

findall和search差不多,只不过时它始终返回一个列表,即使不匹配,也要返回一个空列表[],而search和match返回的是元祖。

result = prog.match(string)
print result.group() group是子元祖,如果显示所有的,就用groups。
result = prog.search(string)
print result.group()
result = prog.findall(string)
print result
split(pattern,string, max=0) 根据正则表达式pattern 中的分隔符把字符string 分割 为一个列表,返回成功匹配的列表,最多分割max 次(默认是分割所有匹配的地方)。 re.split(':','fe:dw:efg')

sub(pattern, repl, string, max=0) 把字符串string 中所有匹配正则表达式pattern 的地方替换成字符串repl,如果max 的值没有给出,则对所有匹配的地方进行替换(另外,请参考subn(),它还会返回一个表示替换次数的数值)。

几种特殊标志flags:

re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)
M(MULTILINE): 多行模式,改变'^'和'$'的行为(参见上图)
S(DOTALL): 点任意匹配模式,改变'.'的行为
L(LOCALE): 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
U(UNICODE): 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
X(VERBOSE): 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。以下两
正则表达式是等价的: DOTALL,前文中已经讲解。 eg:

a = re.compile(r"""\d + # the integral part

. # the decimal point

\d * # some fractional digits""", re.X)

b = re.compile(r"\d+.\d*")

--------EOF---------
微信分享/微信扫码阅读