TPL: 一个新的正则表达式(regex)库
来源:互联网 发布:神经网络的优缺点 知乎 编辑:程序博客网 时间:2024/06/06 07:39
收藏本站 首 页 ┊ 数据库编程 ┊ 开发文档 ┊ Python 与 XML ┊ 热门开源项目 ┊ 交流论坛 ┊ 留 言 您现在的位置:首 页 >> 热门开源项目 >> 正则表达式 >> 查看文章 TPL正则表达式 作者:tamsyn 来源:www.sqlite.com.cn 时间:2008-6-16 【 字体:大 中 小 】 〖 双击滚屏 〗 <iframe border="0" marginwidth="0" marginheight="0" src="http://cm.p4p.cn.yahoo.com/cm?u=http%3A%2F%2Fwww.sqlite.com.cn%2FMySqlite%2F15%2F497.Html&i=un_52773_769_19&w=550&h=80&bd=FFFFFF&tc=0080c0&dc=000000&lc=006600&l=1&ib=1&ad=3&tb=FFFFFF&db=FFFFFF&si=0&k=%D6%D0%CE%C4boost+regex&dt=TPL%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%20--SQLite%20%E4%B8%AD%E6%96%87%E7%A4%BE%E5%8C%BA--%20http%3A%2F%2Fwww.sqlite.com.cn%2F&r=http%3A%2F%2Fwww.baidu.com%2Fs%3Fwd%3D%25D6%25D0%25CE%25C4boost%2Bregex&mk=sqlite%2Csqlite3%2CSQLite%2CSQLite%2Cdatabase%2CSQLite%2C%E5%BC%80%E5%8F%91%2CSQLite%2C%E6%95%B0%E6%8D%AE%E5%BA%93%2CSQLite%2C%E6%95%B0%E6%8D%AE%E5%BA%93%E5%BC%95%E6%93%8E%2CSQLite%2C%E4%B8%AD%E6%96%87%2CSQLite%2C%E4%B8%AD%E6%96%87%E7%A4%BE%E5%8C%BA%2CSQLite%2C%E4%B8%AD%E6%96%87%E8%AE%BA%E5%9D%9B%2CSQLite%2C%E7%BC%96%E7%A8%8B%2CSQLite%2C%E8%AF%AD%E6%B3%95%2CSQLite%2C%E4%B8%8B%E8%BD%BD%2CSQLite%2C%E8%B5%84%E6%96%99%2CSQLite%2C%E5%B5%8C%E5%85%A5%E5%BC%8F%E6%95%B0%E6%8D%AE%2C%E6%9E%97%E8%BD%A9%2C%E6%95%B0%E6%8D%AE%E5%BA%93%2C%E5%B5%8C%E5%85%A5%E5%BC%8F" frameborder="0" height="80" scrolling="no" width="550"></iframe>
TPL: 一个新的正则表达式(regex)库
概要
样例一:识别以空格分隔的浮点数并放入vector中
样例二:识别以逗号分隔的浮点数并放入vector中
样例三:运算器(Calculator)
概要
C++ 中正则表达式(regex)库已经很多。光 boost 中就有3个:regex、spirit、xpressive。那么我们为什么还需要一个新的呢?
多数正则表达式库都需要一个编译(compile)过程。即:通过解释一个正则表达式的字符串(pattern)来生成该正则表达式的内部表示(字节码)。例如 boost regex 就是这样。这类我们称之为动态正则表达式库。
spirit、xpressive 例外。他们直接通过重载 C++ 的操作符来表达一个正则表达式。在你用C++语法描述完一个正则表达式,它已经是内部表示(被C++编译器编译成了机器码)。这一类我们称之为静态正则表达式库。
静态正则表达式库的好处主要有二:
· 性能好。由于匹配代码直接编译成为了机器码,故此通常性能会好过动态的正则表达式。
· 与 C++ 语言可形成良好的互动。可以非常容易在正则表达式中获得执行C++代码的时机。
缺点:
· 正则表达式必须在编译期确定。如果你希望用户可以输入一个正则表达式,那么静态正则表达式库不能直接满足你的需求。
TPL 属于静态正则表达式库。本文也不准备讨论动态正则表达式。需要指出,xpressive 既支持动态正则表达式,也支持静态的正则表达式,但是我们并不考虑其动态正则表达式部分。
TPL 全称为 Text Processing Library(文本处理库)。spirit、xpressive 是很好的东西,实现 TPL 库中对这两者有所借鉴。
说起来开发 TPL 库的理由看起来挺好笑的:原因是 spirit、xpressive 太慢。不是执行慢,而是编译慢。我的机器算起来也不算差,但是每次修改一点点代码,编译过程都等待半天,实在受不了这样的开发效率。
从机理上讲,TPL 并无特别让人振奋之处。该有的 spirit、xpressive 相信都有了。三者都基于“表达式模板(Expression Templates)” 这样的技术。
闲话少说,这里给几个实际的样例让大家感受下:
样例一:识别以空格分隔的浮点数并放入vector中
代码:tpl/test/testtpl/Simplest.cpp
#include <vector>
#include <tpl/RegExp.h>
using namespace tpl;
// What we use:
// * Rules: /assign(), %, real(), ws()
// * Matching: tpl::simple::match()
void simplest()
{
std::vector<double> values; // you can change vector to other stl containers.
if ( simple::match(
"-.1 -0.1 +32. -22323.2e+12",
real()/assign(values) % ws()) )
{
for (
std::vector<double>::iterator it = values.begin();
it != values.end(); ++it)
{
std::cout << *it << "/n";
}
}
}
输出:
-0.1
-0.1
-32
-2.23232e+016
解释:
以上代码我相信比较难以理解的是 / 和 % 算符。
/ 符号我称之为“约束”或“动作”。它是在一个规则(Rule)匹配成功后执行的额外操作。这个额外的操作可能是:
· 使用另一个Rule进行进一步的数据合法性检查。
· 赋值(本例就是)。
· 打印调试信息(正则表达式匹配比较难以跟踪,故此 Debug 能力也是 TPL 的一个关注点)。
· 其他用户自定义动作。
% 符号是列表算符(非常有用)。A % B 等价于 A (B A)* 这样的正则表达式。可匹配 ABABAB..A 这样的串。一个典型案例是用它匹配函数参数列表。
样例二:识别以逗号分隔的浮点数并放入vector中
代码:tpl/test/testtpl/SimpleGrammar.cpp
// A simple grammar example.
// What we use:
// * Rules: /assign(), %, real(), gr(','), skipws()
// * Matching: tpl::simple::match()
void simple_grammar()
{
std::vector<double> values; // you can change vector to other stl containers.
if ( simple::match(
" -.1 , -0.1 , +32. , -22323.2e+12 ",
real()/assign(values) % gr(','), skipws()) )
{
for (
std::vector<double>::iterator it = values.begin();
it != values.end(); ++it)
{
std::cout << *it << "/n";
}
}
}
输出:与样例一相同。
解释:尽管看起来好像没有发生太大的变化。但是这两个样例本质上是不同的。主要体现在:
· 正则表达式的类型不同。real()/assign(values) % ws() 是一个Rule。而 real()/assign(values) % gr(',') 是一个 Grammar。简单来说,Rule 可以认为是词法级别的东西。Grammar 是语法级别的东西。Grammar 的特点在于,它匹配一个语法单元前,总会先调用一个名为Skipper的特殊Rule。上例中 Skipper 为 skipws()。
· 两个 match 的原型不同。第一个match的原型是:match(Source, Rule), 第二个match的原型是:match(Source, Grammar, Skipper)。
第二个例子如果用 Rule 而不是用 Grammar 写,看起来是这样的:
if ( simple::match(
" -.1 , -0.1 , +32. , -22323.2e+12 ",
(skipws() + real()/assign(values)) % (skipws() + ',')) ) ...
你可能认为这并不复杂。单对这个例子而言,确实看起来如此。但是如果你这样想,不妨用 Rule 做下下面这个例子。
样例三:运算器(Calculator)
功能:可处理+-*/四则运算、()、函数调用(sin, cos, pow)。代码:tpl/test/testtpl/Calculator2.cpp (呵呵,只有60行代码哦!)
#include <stack>
#include <tpl/RegExp.h>
#include <tpl/ext/Calculator.h>
#include <cmath>
using namespace tpl;
void calculate2()
{
typedef SimpleImplementation impl;
// ---- define rules ----
impl::Allocator alloc;
std::stack<double> stk;
impl::Grammar::Var rFactor;
impl::Grammar rMul( alloc, '*' + rFactor/calc<std::multiplies>(stk) );
impl::Grammar rDiv( alloc, '/' + rFactor/calc<std::divides>(stk) );
impl::Grammar rTerm( alloc, rFactor + *(rMul | rDiv) );
impl::Grammar rAdd( alloc, '+' + rTerm/calc<std::plus>(stk) );
impl::Grammar rSub( alloc, '-' + rTerm/calc<std::minus>(stk) );
impl::Grammar rExpr( alloc, rTerm + *(rAdd | rSub) );
impl::Rule rFun( alloc,
"sin"/calc(stk, sin) | "cos"/calc(stk, cos) | "pow"/calc(stk, pow) );
rFactor.assign( alloc,
real()/assign(stk) |
'-' + rFactor/calc<std::negate>(stk) |
'(' + rExpr + ')' |
(gr(c_symbol()) + '(' + rExpr % ',' + ')')/(gr(rFun) + '(') |
'+' + rFactor );
// ---- do match ----
for (;;)
{
std::string strExp;
std::cout << "input an expression (q to quit): ";
if (!std::getline(std::cin, strExp) || strExp == "q") {
std::cout << '/n';
break;
}
try {
while ( !stk.empty() )
stk.pop();
if ( !impl::match(strExp.c_str(), rExpr + eos(), skipws()) )
std::cout << ">>> ERROR: invalid expression!/n";
else
std::cout << stk.top() << "/n";
}
catch (const std::logic_error& e) {
std::cout << ">>> ERROR: " << e.what() << "/n";
}
}
}
// -------------------------------------------------------------------------
解释:
· Grammar::Var 用于定义一个未赋值即被引用的Grammar。相应地,我们也有 Rule::Var。
· gr(Rule) 是将一个 Rule 转换为 Grammar。
· SimpleImplementation 是什么?嗯,这个下回聊。
· <tpl/ext/Calculator.h> 并不属于 tpl regex 库。代码也不多。参见:tpl/ext/Calculator.h
下一篇:python模块之sqlite数据库
- TPL: 一个新的正则表达式(regex)库
- TPL: 一个新的正则表达式(regex)库
- TPL: 一个新的C++正则表达式(regex)库
- TPL: 一个新的正则表达式(regex)库
- TPL: 一个新的C++正则表达式(regex)库
- 正则表达式(Regex)
- python中正则表达式库re的使用(regex)
- 简单的正则表达式 Regex
- boost库 -- regex正则表达式
- Boost.Regex库 正则表达式
- 正则表达式(Regex)--(1)
- Python 正则表达式(Regex)
- (正则表达式)Regex类的一些常见使用方式
- (正则表达式)Regex类的一些常见使用方式
- C#正则表达式的使用(Regex类用法)
- C#语言的正则表达式(Regex)详解
- Regex库(c++ 正则表达式)安装小结
- (四)boost库之正则表达式regex
- [SharePoint]设置问卷调查权限
- Dreamweaver 粗略的理一边(也是参考“建站学”网的建站入门)
- 扫雷 源码
- 用C/C++函数调用php功能的问题
- pku 3083 Children of the Candy Corn
- TPL: 一个新的正则表达式(regex)库
- 使用CreateProcess函数运行其他程序
- JAVA面试题解惑系列(一)——类的初始化顺序
- JAVA面试题解惑系列(二)——到底创建了几个String对象?
- PKU 2513 Colored Sticks
- IIS 无法启动:发生意外错误0x8ffe2740 的原因 (感谢AICI大侠的文章)
- JAVA面试题解惑系列(三)——变量(属性)的覆盖
- JAVA面试题解惑系列(四)——final、finally和finalize的区别
- 工作是什么?