Mar 30, 2009

Regular Expression in Python, RegexBuddy

完整的正则表达式规则请参考 Python manual。
以及 Manual 中 Python HOWTO 中 Regular expression HOWTO。

软件方面,推荐使用 RegexBuddy. (或 google  JGsoft.RegexBuddy.v3.5.0.Retail-ZWT.zip)

正则表达式可以编译为 RegexObject,或者直接使用。如果多次使用推荐第一种方法。

字符集可以不带 repetition, 表示出现一次
比如 [abc],匹配 'a','b',或'c'


\d
Matches any decimal digit; this is equivalent to the class [0-9].
\D
Matches any non-digit character; this is equivalent to the class [^0-9].
\s
Matches any whitespace character; this is equivalent to the class [ \t\n\r\f\v].
\S
Matches any non-whitespace character; this is equivalent to the class [^ \t\n\r\f\v].
\w
Matches any alphanumeric character; this is equivalent to the class [a-zA-Z0-9_].
\W
Matches any non-alphanumeric character; this is equivalent to the class [^a-zA-Z0-9_]

非打印字符
You can use special character sequences to put non-printable characters in your regular expression. Use \t to match a tab character (ASCII 0x09), \r for carriage return (0x0D) and \n for line feed (0x0A). More exotic non-printables are \a (bell, 0x07), \e (escape, 0x1B), \f (form feed, 0x0C) and \v (vertical tab, 0x0B). Remember that Windows text files use \r\n to terminate lines, while UNIX text files use \n.


\b 指 \w 和 \W 之间的位置,不对应字符
比如 join's, \b 匹配 j 前,s 后,' 前后四个位置。

[^...] 为 ... 的并集的取反,如 [^\dabcdef],为 \dabcdef 的取反。

方法/属性作用
match()决定 RE 是否在字符串刚开始的位置匹配,返回MatchObject
search()扫描字符串,找到这个 RE 匹配, 返回MatchObject
findall()找到 RE 匹配的所有子串,并把它们作为一个列表返回
finditer()找到 RE 匹配的所有子串,并把它们作为一个迭代器返回
如果没有匹配,match 和 search 会返回 None,findall 返回 []。所以这三种方法可以用 if 来判断是否有匹配。

方法/属性作用
split()去除匹配的RE,并将剩余的字符串分片并生成一个列表,
sub()找到 RE 匹配的所有子串,并将其用一个不同的字符串替换
subn()与 sub() 相同,但以tuple返回新的字符串和替换次数


MatchObject 不仅提供匹配的字符串,还提供匹配的位置。它有如下常用方法:
方法/属性作用
group()返回被 RE 匹配的字符串
start()返回匹配开始的位置
end()返回匹配结束的位置
span()返回一个元组包含匹配 (开始,结束) 的位置

Group:
Group 可以用来分析字符串,将匹配的字符串根据需要分成小组。小组是从左向右计数的,从1开始(0 是整体匹配的 RE)。组可以被嵌套。计数的数值可以能过从左到右计算打开的括号数来确定。m.groups() 返回所有小组(不包含0),m.group(num) 返回第 num 个小组,m.start(num),m.end(num),m.span(num)以此类推。
逆向引用
模式中的逆向引用允许你指定先前捕获组的内容,该组也必须在字符串当前位置被找到。举个例子,如果组 1 的内容能够在当前位置找到的话,\1 就成功否则失败
如下 RE 可以匹配重复的字符串。
(\b\w+)\s+\1\b

(?:...)
Like (...), but does not indicate a group
(?P<id>...)
Like (...), but the group also gets the name id
(?P=id)
Matches whatever was previously matched by group named id
(?#...)
Content of parentheses is just a comment; no effect on match
(?=...)
Lookahead assertion: matches if RE ... matches what comes next, but does not consume any part of the string
(?!...)
Negative lookahead assertion: matches if RE ... does not match what comes next, and does not consume any part of the string
(?<=...)
Lookbehind assertion: matches if there is a match ending at the current position for RE ... (... must match a fixed length)
(?<!...)
Negative lookbehind assertion: matches if there is no match ending at the current position for RE ... (... must match a fixed length)
\number
Matches whatever was previously matched by group numbered number (groups are automatically numbered from 1 to 99)

如果要修改一个 RE,又怕破坏 group 的数字索引,可以使用 non-capturing group,(?...),不会被捕捉,即不会影响数字索引。
如果觉得数字索引很费脑筋,可以选用名字索引, (?P<name>)

Lookaround 零宽度判定:分为 lookahead 和 lookbehind,这些 RE 不消耗字符,而是起到返回是或否的判定作用,判定匹配的 string 前面或后面是否满足 lookahead 或者 lookbehind 的要求。比如寻找不带 u 的 q, 用其他方式都很难表达。q(?!u) 就行了。
>>> t=re.search("q(?!u)","quqd")
>>> t.start()
2
注意各种 RegEx 引擎对于 lookaround 支持的功能不一样。Python 要求必须是定长的。另外 lookbehind 不一定要放在最后面,放在RE 中间也可以。

0 comments: