Qt实现实时正则表达式测试器

前端之家收集整理的这篇文章主要介绍了Qt实现实时正则表达式测试器前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

算是对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. 实时性,即一边输入一边显示结果.

2. 结果的显示方式以高亮的形式进行显示.

在上面这两个简单的需求下,给出实现的代码:

mywindow.h :

  1. /******************************************************************************
  2. ** Coypright(C) 2014-2024 () technology Co.,Ltd
  3. **
  4. ** 文件名 : mywindow.h
  5. ** 版本号 : 1.0
  6. ** 描 述 :
  7. ** 作 者 : cp3alai
  8. ** 日 期 : 2015.06.11
  9. ******************************************************************************/
  10.  
  11. #include <QObject>
  12. #include <QtGui/QApplication>
  13. #include <QtGui/QDesktopWidget>
  14. #include <QtGui/QWidget>
  15. #include <QtGui/QLabel>
  16. #include <QtGui/QTextEdit>
  17. #include <QtGui/QLineEdit>
  18. #include <QtGui/QPushButton>
  19. #include <QtGui/QGridLayout>
  20. #include <QTextCursor>
  21. #include <QtCore/QTextCodec>
  22.  
  23. #include <string>
  24. #include <sstream>
  25.  
  26. #include <boost/filesystem.hpp>
  27. #include <boost/filesystem/fstream.hpp>
  28. #include <boost/xpressive/xpressive.hpp>
  29.  
  30. using namespace std;
  31. using namespace boost::filesystem;
  32. using namespace boost::xpressive;
  33. namespace fs = boost::filesystem;
  34.  
  35. class CMyWindow:public QWidget
  36. {
  37. Q_OBJECT
  38.  
  39. public slots:
  40. void highlightTextMatched(const QString &str);
  41. public:
  42. CMyWindow(QWidget *parent = 0);
  43.  
  44. private:
  45. QLineEdit *m_lineEdit;
  46. QTextEdit *m_textEdit;
  47. QPushButton *m_pushButton;
  48. path m_filename;
  49. fs::fstream m_fstream;
  50. };


mywindow.cpp :

高亮部分的代码借鉴子网络上的代码.

  1. /******************************************************************************
  2. ** Coypright(C) 2014-2024 () technology Co.,Ltd
  3. **
  4. ** 文件名 : mywindow.cpp
  5. ** 版本号 : 1.0
  6. ** 描 述 :
  7. ** 作 者 : cp3alai
  8. ** 日 期 : 2015.06.11
  9. ******************************************************************************/
  10.  
  11. #include "mywindow.h"
  12.  
  13. CMyWindow::CMyWindow(QWidget *parent) : QWidget(parent)
  14. {
  15. QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
  16. m_textEdit = new QTextEdit(this);
  17. m_lineEdit = new QLineEdit(this);
  18. m_pushButton = new QPushButton(this);
  19.  
  20. QGridLayout *gridlayout = new QGridLayout;
  21. //begin 页面布局
  22. m_pushButton->setText("Close");
  23. m_textEdit->setReadOnly(true);
  24.  
  25. gridlayout->addWidget(m_textEdit,5,7);
  26. gridlayout->addWidget(m_lineEdit,1,5);
  27. gridlayout->addWidget(m_pushButton,2);
  28. this->setLayout(gridlayout);
  29. //end 页面布局
  30. m_filename = "./reg.txt";
  31. m_fstream.open(m_filename.string().c_str());
  32.  
  33. stringstream strstream;
  34. strstream<<m_fstream.rdbuf();
  35. string str(strstream.str());
  36. m_textEdit->setPlainText(str.c_str());
  37.  
  38. m_lineEdit->setFocus();
  39. this->setTabOrder(m_lineEdit,m_pushButton);
  40.  
  41. connect(m_lineEdit,SIGNAL(textChanged(QString)),this,SLOT(highlightTextMatched(QString)));
  42. connect(m_pushButton,SIGNAL(clicked()),SLOT(close()));
  43. }
  44.  
  45. void CMyWindow::highlightTextMatched(const QString &str)
  46. {
  47. string wholewords = m_textEdit->toPlainText().toStdString();
  48. this->repaint();
  49. m_textEdit->setPlainText(m_textEdit->toPlainText().toStdString().c_str());
  50.  
  51. if (str.toStdString().empty())
  52. {
  53. return;
  54. }
  55.  
  56. cout<<str.toStdString().at(str.length() - 1)<<endl;
  57.  
  58. string checkstr = str.toStdString();
  59. int little = 0;
  60. int middle = 0;
  61. for (unsigned int i = 0; i < checkstr.length(); i++)
  62. {
  63. if (checkstr[i] == '(')
  64. {
  65. if (i == 0 || (i > 0 && checkstr[i - 1] != '\\'))
  66. {
  67. little++;
  68. }
  69. else if (i > 0 && checkstr[i - 1] == '\\')
  70. {
  71. }
  72. }
  73.  
  74. if (checkstr[i] == '[')
  75. {
  76. if (i == 0 || (i > 0 && checkstr[i - 1] != '\\'))
  77. {
  78. middle++;
  79. }
  80. }
  81.  
  82. if (checkstr[i] == ')')
  83. {
  84. if (i == 0 || (i > 0 && checkstr[i - 1] != '\\'))
  85. {
  86. if (little == 0)
  87. {
  88. return ;
  89. }
  90. little--;
  91. }
  92. }
  93.  
  94. if (checkstr[i] == ']')
  95. {
  96. if (i == 0 || (i > 0 && checkstr[i - 1] != '\\'))
  97. {
  98. if (middle == 0)
  99. {
  100. return ;
  101. }
  102. middle--;
  103. }
  104. }
  105. }
  106.  
  107. if (little != 0 || middle != 0 || str.toStdString().at(str.length() - 1) == '\\')
  108. {
  109. return;
  110. }
  111.  
  112. sregex regex = sregex::compile(str.toStdString(),icase);
  113. smatch match;
  114.  
  115. try
  116. {
  117. regex_search(wholewords,match,regex);
  118. cout<<match[0]<<endl;
  119. }
  120. catch (regex_error &e)
  121. {
  122. cout<<e.what()<<endl;
  123. m_lineEdit->clear();
  124. return;
  125. }
  126.  
  127. QString cQstr = ((string)match[0]).c_str();
  128. cout<<cQstr.toStdString()<<endl;
  129.  
  130. QPalette palette = m_textEdit->palette();
  131. palette.setColor(QPalette::Highlight,palette.color(QPalette::Active,QPalette::Highlight));
  132. m_textEdit->setPalette(palette);
  133.  
  134. m_textEdit->find(cQstr);
  135. }

main.cpp :
  1. /******************************************************************************
  2. ** Coypright(C) 2014-2024 () technology Co.,Ltd
  3. **
  4. ** 文件名 : test.cpp
  5. ** 版本号 : 1.0
  6. ** 描 述 :
  7. ** 作 者 : cp3alai
  8. ** 日 期 : 2015.06.10
  9. ******************************************************************************/
  10.  
  11. #include "mywindow.h"
  12.  
  13. int main(int argc,char ** argv)
  14. {
  15. QApplication app(argc,argv);
  16. QDesktopWidget *desk;
  17. CMyWindow *mywindow = new CMyWindow;
  18.  
  19. mywindow->setWindowTitle(("正则练习器"));
  20. mywindow->resize(500,500);
  21. mywindow->show();
  22.  
  23. desk = QApplication::desktop();
  24. mywindow->move((desk->width() - mywindow->width())/2,(desk->height() - mywindow->height())/2);
  25.  
  26. return app.exec();
  27. }

使用方法:

在当前目录下建立一个reg.txt的文件,然后随便填一些内容即可加载.

效果如下:

可能代码中还存在一些瑕疵,如果哪位同学发现了,还望指教.谢谢!!!

猜你在找的正则表达式相关文章