正则表达式使用学习(C++、Qt、Python)

写在前面

个人对于正则表达式实在是不太了解,所以本文内容纰漏应该会比较多。只希望不会对大家造成误导。

本文只是简单涉及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 只是一个别名 typedef basic_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中:

regex_replace()

就这一个么?呵呵

参考

  • 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

你可能感兴趣的:(C++,正则表达式,python,iterator,regex,qt)