TPL: 一个新的正则表达式(regex)库

2024-01-07 11:58
文章标签 正则表达式 regex tpl

本文主要是介绍TPL: 一个新的正则表达式(regex)库,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

POP Article V2.0设为主页
收藏本站
<script src="http://www.sqlite.com.cn/POPinc/POPmenu.js"></script>首 页<script src="http://www.sqlite.com.cn/POPinc/POPnav.js"></script> ┊ 数据库编程 ┊ 开发文档 ┊ Python 与 XML ┊ 热门开源项目 ┊ 交流论坛 ┊ 留 言
您现在的位置:首 页 >> 热门开源项目 >> 正则表达式 >> 查看文章
TPL正则表达式
作者:tamsyn  来源:www.sqlite.com.cn  时间:2008-6-16  【 字体:大 中 小 】 〖 双击滚屏 〗
<script type="text/JavaScript"> var yahoo_pid="un_52773_769_19"; var yahoo_bordercolor="FFFFFF"; var yahoo_titlecolor="0080c0"; var yahoo_descolor="000000"; var yahoo_linkcolor="006600"; var yahoo_titlebgcolor="FFFFFF"; var yahoo_desbgcolor="FFFFFF"; var yahoo_width=550; var yahoo_height=80; var yahoo_isbanner=1; var yahoo_displink=1; var yahoo_adsnum=3; var yahoo_simple=0; var yahoo_iniframe=1; </script> <script type="text/javascript" src="http://cm.p4p.cn.yahoo.com/inf.js"></script> 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">

TPL: 一个新的正则表达式(regex)库

 

概要

样例一:识别以空格分隔的浮点数并放入vector

样例二:识别以逗号分隔的浮点数并放入vector

样例三:运算器(Calculator

 

概要

C++ 中正则表达式(regex)库已经很多。光 boost 中就有3个:regexspiritxpressive。那么我们为什么还需要一个新的呢?

多数正则表达式库都需要一个编译(compile)过程。即:通过解释一个正则表达式的字符串(pattern)来生成该正则表达式的内部表示(字节码)。例如 boost regex 就是这样。这类我们称之为动态正则表达式库。

spiritxpressive 例外。他们直接通过重载 C++ 的操作符来表达一个正则表达式。在你用C++语法描述完一个正则表达式,它已经是内部表示(被C++编译器编译成了机器码)。这一类我们称之为静态正则表达式库。

静态正则表达式库的好处主要有二:

·         性能好。由于匹配代码直接编译成为了机器码,故此通常性能会好过动态的正则表达式。

·         C++ 语言可形成良好的互动。可以非常容易在正则表达式中获得执行C++代码的时机。

缺点:

·         正则表达式必须在编译期确定。如果你希望用户可以输入一个正则表达式,那么静态正则表达式库不能直接满足你的需求。

TPL 属于静态正则表达式库。本文也不准备讨论动态正则表达式。需要指出,xpressive 既支持动态正则表达式,也支持静态的正则表达式,但是我们并不考虑其动态正则表达式部分。

TPL 全称为 Text Processing Library(文本处理库)。spiritxpressive 是很好的东西,实现 TPL 库中对这两者有所借鉴。

说起来开发 TPL 库的理由看起来挺好笑的:原因是 spiritxpressive 太慢。不是执行慢,而是编译慢。我的机器算起来也不算差,但是每次修改一点点代码,编译过程都等待半天,实在受不了这样的开发效率。

从机理上讲,TPL 并无特别让人振奋之处。该有的 spiritxpressive 相信都有了。三者都基于表达式模板(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

 

浏览次数:<script src="http://www.sqlite.com.cn/POPinc/POPjs.asp?action=POPhit&id=497"></script>292   【 打 印 】【 关 闭 】
上一篇:Python之简洁ini读写
下一篇:python模块之sqlite数据库

这篇关于TPL: 一个新的正则表达式(regex)库的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/579839

相关文章

JavaScript正则表达式六大利器:`test`、`exec`、`match`、`matchAll`、`search`与`replace`详解及对比

在JavaScript中,正则表达式(Regular Expression)是一种用于文本搜索、替换、匹配和验证的强大工具。本文将深入解析与正则表达式相关的几个主要执行方法:test、exec、match、matchAll、search和replace,并对它们进行对比,帮助开发者更好地理解这些方法的使用场景和差异。 正则表达式基础 在深入解析方法之前,先简要回顾一下正则表达式的基础知识。正则

匹配电子邮件地址的正则表达式

这个正则表达式 QRegularExpression regex(R"((\w+)(\.|_)?(\w+)@(\w+)(\.(\w+))+))"); 用于匹配电子邮件地址的格式。下面是对这个正则表达式的逐步解析和解释: 1. QRegularExpression 构造函数 QRegularExpression regex(R"((\w+)(\.|_)?(\w*)@(\w+)(\.(\w+))+

notepad++ 正则表达式多条件查找替换

基础语法参考: https://www.cnblogs.com/winstonet/p/10635043.html https://www.linuxidc.com/Linux/2019-05/158701.htm   通常情况下我们查找的内容和要被替换掉的内容是一样的,我们只需要使用正则表达式精确框定查找内容,替换直接输入要替换的内容即可。 但有时会比较复杂,查找的内容,只需要替换其中

js正则表达式test方法的问题

今天在网上碰到一个帖子,写了一个关于Regex的奇怪现象,(文章来源http://www.php100.com/html/webkaifa/javascript/2007/0109/1866.html) 代码如下 <script type="text/javascript"><!--var re = /^\d+(?:\.\d)?$/ig; alert(re.test('112.3'

Java利用正则表达式获取指定两个字符串之间的内容

package com.starit.analyse.util;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern;public class DealSt

AS3中正则表达式中如何表达“或”

var reg:RegExp=/\r|\n|\t/g;                 var msg:String="123\rabc\n\tabc\ta\123";                 msg=msg.replace(reg,"");                 trace(msg);

as3 正则表达式(比较齐全)

正则表达式是AS3比较重要的一个部分,具体内容如下:   //正则表达式有四个部分。1元子符。2元序列。3标志。4数量表达符。 //下面是元字符部分 //现在我们来看看元字符: ^ $ \ . * + ? ( ) [ ] { } | //^匹配字符串的开头 varpattern:RegExp=/^小虫/; var str:String="小虫是好人"; trace(str, " is

as3 常用正则表达式(来自天地会论坛之七夜)

正则表达式是一种通用的标准,大部分计算机语言都支持正则表达式,包括as3,这里转摘出了一些常用的正则表达式语句,大家用到的时候就不用自己写了。 红色字体为常用正则: 下面这个类是我自己写的一个示例,想必大家做客户端,用户登录信息肯定会用的正则表达式。 package com.qiye.regexp { /**   * 常用正则表达式。   * @author Qiy

认识正则表达式

为什么要学习正则表达式 因为爬虫需要!!! 一般来说爬虫需要四个主要步骤: 明确目标 (要知道你准备在哪个范围或者网站去搜索)爬 (将所有的网站的内容全部爬下来)取 (去掉对我们没用处的数据)处理数据(按照我们想要的方式存储和使用) 一般情况我们拉取的网页数据庞大并且很混乱,其中很大一部分东西是我们不关心的,因此我们需要将其按要求过滤和匹配出来。 那么对于文本的过滤和指定规则的匹配,最

C语言的一个正则表达式pcre

1. 简介 在C/C++中,一个比较好的正则表达式是pcre,被很多工具(包括一些商用工具)使用。 2. 源码下载&安装 2.1 下载 可以从官网http://www.pcre.org/下载,为方便学习,已放在这里http://download.csdn.net/detail/u013344915/7793027。 2.2 Windows上的安装过程 参考:Windows上面编译pc