算是对boost学习的小结,当然也并没有完全看完boost,内容很多.只是看了一些常用的内容.
本篇文章将接合对boost正则表达式的学习,完成一个正则表达式测试器.UI借助了QT的实现.
首先当然是对boost的正则表达式的介绍.
boost有两个正则表达式解析器.一个是xpressive.还有另外一个叫regex.
没去了解regex,相比使用方法没有太大差异.仅就xpressive做简单的介绍.
xpressive有三个头文件:
xpressive_static.h : 静态的正则匹配方式,可以在编译期完成.本文不做讨论.
xpressive_dynamic.h : 动态的正则匹配方式.
xpressive.h : 上面的两个都包括.
xpressive的三个重要的类 :
basic_regex : 这个模板类是核心,封装了正则表达式的解析和编译的动作.但是使用的时候不直接使用这个类.而是使用它的两个typedef : cregex(char的正则) 和 sregex(string的正则)
match_results : 这个模板类保存正则表达式匹配的结果.使用的时候同样是使用它的两个typedef : cmatch(同上) 和 smatch(同上).
sub_match : 这个类只在分词的时候会用到,作用与match_results类似.
xpressive支持五种基于正则表达式的操作:
匹配 : 即完整匹配.借助全局函数regex_match来实现.函数原型为 bool regex_match(string,match_results &,basic_regex &);其中第一个参数为源数据,第二个参数是保存匹配后的结果.第三个参数就是正则表达式.
这里着意了解一下第二个参数,既然是完全匹配,为什么还需要第二个参数来保存结果呢,因为第二个参数是一个结果集.重载了[],下标0保存的是完整匹配的内容,从1开始保存的是匹配的子表达式(即通过小括号括起来的正则表达式匹配到的内容).
查找 : 只要部分匹配即返回真.函数原型为 bool regex_search(string,basic_regex &); 参数的含义与匹配是一样的.
替换 : 使用过sed命令的同学肯定都用过这样的用法.sed "s/from/to/g",在这里是同样的意思.需要借助全局函数 regex_replace(string,basic_regex const &,format);前两个参数分别是源字符串和正则表达式.最后一个参数format就是需要把basic_regex匹配的内容替换成的字符串.注意可以使用$N来作为子表达式的占位符.
迭代 : cregex_iterator 和 sregex_iterator,借助的是match_results类.可以迭代正则表达式匹配的结果.用法也很简单,只要使用其自身的构造函数即可实现迭代.
regex_iterator(string begin,string end,basic_regex&).第一个参数表示字符串的开头,第二个参数表示字符串的结尾.第三个参数即为正则表达式.
分词 : 所谓分词其实也可以理解成一种迭代.不过它所涉及的范围更广,不仅可以迭代匹配的内容,还可以迭代不匹配的内容.在使用的时候只要实例化两个类中的一个即可:cregex_token_iterator 和 sregex_token_iterator.这个功能也是借助自身构造函数实现的 : regex_token_iterator(string begin,basic_regex,match_type);前三个参数和迭代是一样的意思,最后一个参数用来标记分词的内容(把匹配的分出来还是把不匹配的分出来).
本文只是简单的对boost的正则表达式做了入门级的介绍,如果同学们想要进一步的学习,推荐大家看一下<<boost程序完全开发指南>>,很不错的一本书,每一个知识点都有一个对应的小例子,很方便学习.
下面来设计一下正则表达式练习器.
1. 实时性,即一边输入一边显示结果.
在上面这两个简单的需求下,给出实现的代码:
mywindow.h :
- /******************************************************************************
- ** Coypright(C) 2014-2024 () technology Co.,Ltd
- **
- ** 文件名 : mywindow.h
- ** 版本号 : 1.0
- ** 描 述 :
- ** 作 者 : cp3alai
- ** 日 期 : 2015.06.11
- ******************************************************************************/
- #include <QObject>
- #include <QtGui/QApplication>
- #include <QtGui/QDesktopWidget>
- #include <QtGui/QWidget>
- #include <QtGui/QLabel>
- #include <QtGui/QTextEdit>
- #include <QtGui/QLineEdit>
- #include <QtGui/QPushButton>
- #include <QtGui/QGridLayout>
- #include <QTextCursor>
- #include <QtCore/QTextCodec>
- #include <string>
- #include <sstream>
- #include <boost/filesystem.hpp>
- #include <boost/filesystem/fstream.hpp>
- #include <boost/xpressive/xpressive.hpp>
- using namespace std;
- using namespace boost::filesystem;
- using namespace boost::xpressive;
- namespace fs = boost::filesystem;
- class CMyWindow:public QWidget
- {
- Q_OBJECT
- public slots:
- void highlightTextMatched(const QString &str);
- public:
- CMyWindow(QWidget *parent = 0);
- private:
- QLineEdit *m_lineEdit;
- QTextEdit *m_textEdit;
- QPushButton *m_pushButton;
- path m_filename;
- fs::fstream m_fstream;
- };
mywindow.cpp :
- /******************************************************************************
- ** Coypright(C) 2014-2024 () technology Co.,Ltd
- **
- ** 文件名 : mywindow.cpp
- ** 版本号 : 1.0
- ** 描 述 :
- ** 作 者 : cp3alai
- ** 日 期 : 2015.06.11
- ******************************************************************************/
- #include "mywindow.h"
- CMyWindow::CMyWindow(QWidget *parent) : QWidget(parent)
- {
- QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
- m_textEdit = new QTextEdit(this);
- m_lineEdit = new QLineEdit(this);
- m_pushButton = new QPushButton(this);
- QGridLayout *gridlayout = new QGridLayout;
- //begin 页面布局
- m_pushButton->setText("Close");
- m_textEdit->setReadOnly(true);
- gridlayout->addWidget(m_textEdit,5,7);
- gridlayout->addWidget(m_lineEdit,1,5);
- gridlayout->addWidget(m_pushButton,2);
- this->setLayout(gridlayout);
- //end 页面布局
- m_filename = "./reg.txt";
- m_fstream.open(m_filename.string().c_str());
- stringstream strstream;
- strstream<<m_fstream.rdbuf();
- string str(strstream.str());
- m_textEdit->setPlainText(str.c_str());
- m_lineEdit->setFocus();
- this->setTabOrder(m_lineEdit,m_pushButton);
- connect(m_lineEdit,SIGNAL(textChanged(QString)),this,SLOT(highlightTextMatched(QString)));
- connect(m_pushButton,SIGNAL(clicked()),SLOT(close()));
- }
- void CMyWindow::highlightTextMatched(const QString &str)
- {
- string wholewords = m_textEdit->toPlainText().toStdString();
- this->repaint();
- m_textEdit->setPlainText(m_textEdit->toPlainText().toStdString().c_str());
- if (str.toStdString().empty())
- {
- return;
- }
- cout<<str.toStdString().at(str.length() - 1)<<endl;
- string checkstr = str.toStdString();
- int little = 0;
- int middle = 0;
- for (unsigned int i = 0; i < checkstr.length(); i++)
- {
- if (checkstr[i] == '(')
- {
- if (i == 0 || (i > 0 && checkstr[i - 1] != '\\'))
- {
- little++;
- }
- else if (i > 0 && checkstr[i - 1] == '\\')
- {
- }
- }
- if (checkstr[i] == '[')
- {
- if (i == 0 || (i > 0 && checkstr[i - 1] != '\\'))
- {
- middle++;
- }
- }
- if (checkstr[i] == ')')
- {
- if (i == 0 || (i > 0 && checkstr[i - 1] != '\\'))
- {
- if (little == 0)
- {
- return ;
- }
- little--;
- }
- }
- if (checkstr[i] == ']')
- {
- if (i == 0 || (i > 0 && checkstr[i - 1] != '\\'))
- {
- if (middle == 0)
- {
- return ;
- }
- middle--;
- }
- }
- }
- if (little != 0 || middle != 0 || str.toStdString().at(str.length() - 1) == '\\')
- {
- return;
- }
- sregex regex = sregex::compile(str.toStdString(),icase);
- smatch match;
- try
- {
- regex_search(wholewords,match,regex);
- cout<<match[0]<<endl;
- }
- catch (regex_error &e)
- {
- cout<<e.what()<<endl;
- m_lineEdit->clear();
- return;
- }
- QString cQstr = ((string)match[0]).c_str();
- cout<<cQstr.toStdString()<<endl;
- QPalette palette = m_textEdit->palette();
- palette.setColor(QPalette::Highlight,palette.color(QPalette::Active,QPalette::Highlight));
- m_textEdit->setPalette(palette);
- m_textEdit->find(cQstr);
- }
main.cpp :
- /******************************************************************************
- ** Coypright(C) 2014-2024 () technology Co.,Ltd
- **
- ** 文件名 : test.cpp
- ** 版本号 : 1.0
- ** 描 述 :
- ** 作 者 : cp3alai
- ** 日 期 : 2015.06.10
- ******************************************************************************/
- #include "mywindow.h"
- int main(int argc,char ** argv)
- {
- QApplication app(argc,argv);
- QDesktopWidget *desk;
- CMyWindow *mywindow = new CMyWindow;
- mywindow->setWindowTitle(("正则练习器"));
- mywindow->resize(500,500);
- mywindow->show();
- desk = QApplication::desktop();
- mywindow->move((desk->width() - mywindow->width())/2,(desk->height() - mywindow->height())/2);
- return app.exec();
- }
使用方法:
在当前目录下建立一个reg.txt的文件,然后随便填一些内容即可加载.
效果如下:
可能代码中还存在一些瑕疵,如果哪位同学发现了,还望指教.谢谢!!!