|
写在前面
个人对于正则表达式实在是不太了解,所以本文内容纰漏应该会比较多。只希望不会对大家造成误导。
本文只是简单涉及C++0x、Qt4、Python3、Vim中的正则表达式:
C++0x:在 regexp 头文件中提供一系列模板类
Qt4:中提供了 QRegExp 类
Python3:中提供了 re 模块
Vim:命令模式和脚本支持正则
晕,写了一上午,竟然写成了这样了,Vim竟然都没涉及,其他部分也是一团糟,额,本来是想整理它们之间的在pattern上的区别的。不管了,先这样吧。
2011.08.20
用途
两个问题+三个动作?(真不知道该如何分类了...):
match: 字符串匹配这个模式(pattern)么?
search: 字符串中存在和模式匹配的字串么?
capture: 捕获匹配的字符串
replace: 替换字符串(子串)
split: 分割字符串
使用
准备pattern字符串
这个?元字符、匹配单个字符、重复匹配等,似乎相关的资料太多了哈,这儿暂时省略。
Python提供raw字符串的字面量写法,C++0x也提供了这种功能,只是编译器目前似乎都尚不支持。
//C++0x
const char * str1 = "C://windows//system32";
const char * str2 = R"(C/windows/system32)";
生成pattern对象
Python
|
re.compile(pattern, flags=0)生成对象
|
Qt
|
使用QRegExp构造函数,可通过QRegExp::setPattern()修改
|
C++0x
|
通过模板类basic_regex构造
|
Python 下面,通过 re.compile() 可以生成一个正则表达式对象(Regular Expression Objects)
>>> import re
>>> re.compile(r"dbzhang8\d{2}")
<_sre.SRE_Pattern object at 0xb731c720>
>>>
如果稍后只是使用re模块级的函数,比如re.match(r"dbzhang8\d{2}","dbzhang800"),那么不必先使用compile生成正则表达式对象。
C++0x 和 Qt 下,直接使用构造函数生成对象
QRegExp qt_pattern("dbzhang8\\d{2}");
std::regex cpp_pattern("dbzhang8\\d{2}");
在C++0x中,有char,wchar_t,char16_t,char32_t 这4种字符类型,std::regex 只是一个别名typedefbasic_regex<char>regex;
执行匹配操作
看看Python
match()
|
判断RE是否从字符串“开头”开始匹配
|
成功则返回一个MatchObject对象,否则返回None
|
这4个函数均有模块级 和 对象的成员函数两种形式。区别在于后者需要先编译一个正则表达式对象,该对象可以重复使用。
|
search()
|
扫描字符串,看是否有匹配的字串
|
findall()
|
查找所有匹配的字串,将它们作为一个list返回
|
|
finditer()
|
查找所有匹配的字串,将它们以迭代器(iterator)返回
|
|
- 简单的例子:
>>> p = re.compile(r"dbzhang8\d{2}")
>>> print(p.match("dbzhang-800"))
None
>>> p.match("dbzhang801")
<_sre.SRE_Match object at 0xb71d3fa8>
>>> p.findall("dbzhang801dbzhang802")
['dbzhang801', 'dbzhang802']
注意:MatchObject包含匹配信息,可以用来提取匹配的字符串
看看Qt
QRegExp::exactMatch()
|
判断字符串是否完全(从头到尾)匹配,返回真或假
|
这3个操作都会设置 matchedLength()、capturedTexts()、pos()的信息,类似于前面python中的MatchObject
|
QRegExp::indexIn()
|
搜索字符串以找到匹配的字串,返回索引值,失败返回-1
|
QRegExp::lastIndexIn()
|
同上,只是从后向前搜索
|
QString::indexOf()
|
|
如果只是查找的话,这两个更方便,只是无法获取额外的capturedTexts等信息了
|
QString::contains()
|
是否匹配
|
QString::count()
|
多少次匹配
|
恩,看看C++0x
regex_match()
|
表达式是否完整匹配一个字符串?
|
返回值是布尔量,但执行时会填充一个match_results对象,以用来进行字串捕捉。注意:这些是算法,不是前面提到的basic_regex的成员函数。
|
regex_search()
|
是否匹配字符串的一部分?
|
看看Capture信息?
要Capture字串的话,正则的pattern需要使用圆括号“()”包住一部分。
前面看到,match、search、index、... 等操作,都会通过其他方式填充一些额外的信息
Python 中生成一个 MatchObject 对象
- C++ 0x 填充 match_result 对象
- Qt 通过QRegExp对象自身 matchedLength()、capturedTexts()、pos() 的成员函数
Python
group()
|
返回匹配的字符串
|
需指定哪一个(或哪几个)组,默认是0组(匹配自身)
|
start()
|
返回匹配的起始位置
|
end()
|
返回匹配的结束位置
|
span()
|
返回包含起始和结束位置的元组(tuple)
|
groups()
|
返回所有匹配的组
|
|
Qt 中:
matchedLength()
|
匹配的长度
|
|
captureCount()
|
表达式中含有的捕捉组的数目
|
|
capturedTexts()
|
捕捉到的字符串列表
|
pos(int n)
|
第n个组的位置
|
cap(int n)
|
第n个组的内容(0代表匹配自身)
|
C++0x 中:
match_results::operator[](size_type n)
|
返回第n个捕捉组(0代表匹配自身)
|
返回的是sub_match模板类的对象
|
match_results::prefix()
|
返回被匹配子串前面的串
|
match_results::suffix()
|
返回被匹配子串后面的串
|
match_results::empty()
|
只在匹配失败是返回true
|
|
match_results::size()
|
组的数目
|
|
match_results::str()
|
组的内容
|
|
match_results::position()
|
位置
|
|
- 4个别名:
typedef match_results<const char*> cmatch;
typedef match_results<const wchar_t*> wcmatch;
typedef match_results<string::const_iterator> smatch;
typedef match_results<wstring::const_iterator> wsmatch;
执行修改操作
Python
split()
|
分割字符串
|
可指定最大分割或替代的数目
|
sub()
|
替换所有匹配的子串
|
subn()
|
同上,但同时返回多少次替换发生(返回的是元组)
|
Qt中:
QString::split()
|
全是QString的成员函数,简单明了
|
QString::section()
|
QString::replace()
|
QString::remove()
|
C++0x中:
参考
http://docs.python.org/howto/regex.html
http://docs.python.org/py3k/library/re.html
http://doc.qt.nokia.com/4.7/qstring.html
http://doc.qt.nokia.com/4.7/qregexp.html
http://www.greenend.org.uk/rjk/2002/06/regexp.html
|
|
|