/*正则表达式(编写程序的时候,注意双层转义字符解析,(有两次转义字符解析))
see also :
http://blog.csdn.net/c05170519/article/details/6873440/
上述网页讲述了正则表达式的规则,但实际使用时要注意每个'\'符号前面要
重复加一个'\',见18行
*/
#include <QCoreApplication>
#include <QRegExp>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//QRegExp demo("\d+");
//QRegExp rx("^\d\d?$");
//我们的意图是让正则表达式匹配字符串中的'\'字符,你可能说,两个'\'(即"\\")不就行了,
//但确实不行,我们将字符串形式的'\\\\',传入QRegExp构造函数时,C++中自带的字符串解析
//帮我们做了第一层转义字符解析,这是我们rx对象内部的正则表达式变成"\\",去掉了第1个和第
//3个'\'(注意解析所去掉的是第几个'\'),接下来正则表达式内部规则再做第二次转义字符解析
//最终正则表达式的意图变为"\",即字符串中是否有'\',
//所以我们使用QRegExp类时,先按照上述网页中所说规则书写完成,然后在书写好的字符串中
//每个'\'前面再填一个'\',才能满足两次转义字符的解析
//我们的意图是搜索字符串中是否含有反斜杠'\'
//1.根据意图写出表达式"\\"
//2.再加上C/C++中字符串存在的转义字符解析,所以要在每个'\'前加一个'\',的最终表达式'\\\\'
QRegExp rx("\\\\");
cout <<"mathc position = "<< rx.indexIn("1231\\") << endl;
QString str = "offsets: 1.23 .50 71.00 6.00";
//下面以此为例搜索字符串中是否存在小数(小数的整数部分可以为空)
//1.按照意图写出正则表达式"\d*\.\d+"(\d为匹配任意数字,*表示前面字符的个数>=0, +表示前面字符的个数>=1)
//2.根据两次转义字符解析,的"\\d*\\.\\d+"
QRegExp rx2("\\d*\\.\\d+"); // primitive floating point matching
int count = 0;
int pos = 0;
//这里QRegex::indexIn()函数可以替换为QString::indexOf(QRegex)函数
while ((pos = rx2.indexIn(str, pos)) != -1) {
++count;
//matchedLength()函数返回匹配字符串的长度,一般在调用完indexIn()函数或exactMatch()函数后调用
//indexIn()在字符串的子串中搜索是否有满足正则表达式的子串,有返回子串的位置,否则返回-1
//exactMatch(QString &)函数是字符串严格和正则表达式匹配后返回true,否则返回false
int length = rx2.matchedLength();
pos += length;
cout << "lenth =" << length << endl;
cout << "pos = " << pos << endl;
}
// pos will be 9, 14, 18 and finally 24; count will end up as 4
QRegExp rx3(".\\b");// \b不匹配任何实际的字符,只表示字母和非字母的分界
cout << "position = " << rx3.indexIn("@@@abc") << endl;
cout << "str is " << rx3.cap(0).toStdString() << endl;//详见以下介绍
cout << "length = " << rx3.matchedLength() << endl;
QRegExp rx4("\\bend\\b");
cout << "position = " << rx4.indexIn("weekend,endfor,end") << endl;
cout << "length = " << rx4.matchedLength() << endl;
//cap(int nth=0)函数返回和对应的子表达式匹配的字符串,参数nth为子表达式的编号,默认为整个大表达式
//eg 如下
//子表达式0,代表整个正则表达式,子表达式1,代表(\\+d), 子表达式2代表(cm|inch),因为(?:\\s*)表达式中
//?:将此子表达式忽略,若不用?: 下面rxlen.cap(2) 应该返回空,而不是cm,rxlen(3)返回cm
QRegExp rxlen("(\\d+)(?:\\s*)(cm|inch)");
pos = rxlen.indexIn("Length: 189cm");
if (pos > -1) {
QString value = rxlen.cap(1); // "189"
QString unit = rxlen.cap(2); // "cm"
// ...
cout << rxlen.cap(0).toStdString() << endl;
cout << value.toStdString() << endl;
cout << unit.toStdString() << endl;
cout << rxlen.cap(3).toStdString() << endl;
}
/*注意,这里匹配括号,和linux中sed grep等命令的不同
*grep sed 后跟的正则表达式中(的特殊含义默认是关闭的,要使用\(开启
* 而这里正好相反,(对正则表达式的特殊含义默认是开启的,要使用\(关闭
* 例如shell中使用grep 匹配以(开头的行 cat xx.txt | grep '^('
* 而这里却要使用\(关闭括号的特殊含义,详见linux笔记
*/
QRegExp rx5("\\(\\w*\\)");
pos = rx5.indexIn("(weiyuyin)");
if(pos > -1)
{
cout << rx5.cap(0).toStdString() << endl;
}
return a.exec();
}