11_Boost

【目录】

一、 Boost入门 2
二、 Boost::array: 4
1、 范例: 4
三、 Boost::bind 4
1、 范例: 4
四、 Boost::function 5
1、 范例: 5
五、 Boost::ref 和 boost::cref 7
1、 介绍: 7
2、 范例: 7
六、 C++ RAII 资源获取即初始化 8
1、 简介: 8
2、 特点: 8
3、 范例: 9
七、 Std::auto_ptr ——智能指针 9
1、 介绍: 9
2、 范例: 10
八、 Boost::scoped_ptr作用域指针 11
1、 简介: 11
2、 范例: 11
九、 Boost::thread 14
1、 范例: 14
十、 Boost::unordered 15
1、 范例: 15
十一、 Boost::regex 正则 16
1、 简介: 16
2、 特殊字符介绍 16
3、 类的特性模板参数(the traits template parameter)。 16
4、 范例: 23

一、Boost入门

①.boost是一个准标准库,相当于STL的延续和扩充,它的设计理念和STL比较接近,都是利用泛型让复用达到最大化。不过对比STL,boost更加实用。STL集中在算法部分,而boost包含了不少工具类,可以完成比较具体的工作。
②.boost主要包含一下几个大类:字符串及文本处理、容器、迭代子(Iterator)、算法、函数对象和高阶编程、泛型编程、模板元编程、预处理元编程、并发编程、数学相关、纠错和测试、数据结构、输入/输出、跨语言支持、内存相关、语法分析、杂项。 有一些库是跨类别包含的,就是既属于这个类别又属于那个类别。
③.在文本处理部分,conversion/lexcial_cast类用于“用C++”的方法实现数字类型和字符串之间的转换。 主要是替代C标准库中的 atoi、 itoa之类的函数。当然其中一个最大的好处就是支持泛型了。
④.format库提供了对流的“printf-like”功能。printf里使用%d、%s等等的参数做替换的方法在很多情况下还是非常方便的,STL的iostream则缺乏这样的功能。format为stream增加了这个功能,并且功能比原始的printf更强。
⑤.regex,这个不多说了,正则表达式库。如果需要做字符串分析的人就会理解正则表达式有多么有用了。
⑥.spirit,这个是做LL分析的框架,可以根据EBNF规则对文件进行分析。(不要告诉我不知道什么是EBNF)。做编译器的可能会用到。一般人不太用的到。
⑦.tokenizer库。我以前经常在CSDN上看到有人问怎么把一个字符串按逗号分割成字符串数组。也许有些人很羡慕VB的split函数。现在,boost的tokenizer也有相同的功能了,如果我没记错的话,这个tokenizer还支持正则表达式,是不是很爽?
⑧.array: 提供了常量大小的数组的一个包装,喜欢用数组但是苦恼数组定位、确定数组大小等功能的人这下开心了。
⑨.dynamic_bitset,动态分配大小的bitset,我们知道STL里有个bitset,为位运算提供了不少方便。可惜它的大小需要在编译期指定。现在好了,运行期动态分配大小的bitset来了。
⑩.graph。提供了图的容器和相关算法。我还没有在程序中用到过图,需要用的人可以看看。
⑪.multi_array提供了对多维数组的封装,应该还是比较有用的。
⑫.并发编程里只有一个库,thread,提供了一个可移植的线程库,不过在Windows平台上我感觉用处不大。因为它是基于Posix线程的,在Windows里对Posix的支持不是很好。
⑬.接下来的 数学和数值 类里,包含了很多数值处理方面的类库,数学类我也不太熟,不过这里有几个类还是很有用的,比如rational分数类,random随机数类,等等。
⑭.static_assert,提供了编译器的assert功能。
⑮.test库,一个单元测试框架,非常不错。
⑯.concept_check提供了泛型编程时,对泛型量的一点检查,不是很完善,不过比没有好。
⑰.数据类型类any,一个安全的可以包含不同对象的类。把它作为容器的元素类型,那么这个容器就可以包含不同类型的元素。比用void *要安全。
⑱.compressed_pair,跟STL里的pair差不多。不过对空元素做了优化。
⑲.tuple,呵呵,也许是某些人梦寐以求的东西。可以让函数返回多个值。
⑳.跨语言支持:Python,呵呵,好东东啊,可以将C++的类和函数映射给python使用。以下为几个CSDN上的关于boost.python的中文资料:http://dev.csdn.NET/article/19/19828.shtmhttp://dev.csdn.net/article/19/19829.shtmhttp://dev.csdn.net/article/19/19830.shtmhttp://dev.csdn.net/article/19/19831.shtm
21.pool:内存池,呵呵,不用害怕频繁分配释放内存导致内存碎片,也不用自己辛辛苦苦自己实现了。
22.smart_ptr:智能指针,这下不用担心内存泄漏的问题了吧。不过,C++里的智能指针都还不是十全十美的,用的时候小心点了,不要做太技巧性的操作了。
23.date_time,这个是平台、类库无关的实现,如果程序需要跨平台,可以考虑用这个。
24.timer,提供了一个计时器,虽然不是Windows里那种基于消息的计时器,不过据说可以用来测量语句执行时间。
25.uitlity里提供了一个noncopyable类,可以实现“无法复制”的类。很多情况下,我们需要避免一个类被复制,比如代表文件句柄的类,文件句柄如果被两个实例共享,操作上会有很多问题,而且语义上也说不过去。一般的避免实例复制的方法是把拷贝构造和operator=私有化,现在只要继承一下这个类就可以了,清晰了很多。
26.value_initialized:数值初始化,可以保证声明的对象都被明确的初始化,不过这个真的实用吗?似乎写这个比直接写初始化还累。呵呵,仁者见仁了。
27.这里面除了regex、python和test需要编译出库才能用,其他的大部分都可以直接源代码应用,比较方便。其实这些库使用都不难。最主要的原因是有些库的使用需要有相关的背景知识,比如元编程、STL、泛型编程等等。

二、Boost::array:

1、范例:

#include<boost/array.hpp>
#include <iostream>
#include <string>

using namespace std;

using namespace boost;

void mainA ()
{
    Boost::array <int, 5> barray = { 1, 2, 3, 4, 5 };
    barray[0] = 10;
    barray.at(4) = 20;
    int *p = barray.data();//存储数组的指针
    for (int i = 0; i < barray.size();i++)
    {
        cout << barray[i] << "  " << p[i] << endl;
    }

    array<string, 3> cmd = { "calc", "notepad", "tasklist" };

    cin.get();
}

三、Boost::bind

1、范例:

#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
using namespace boost;

//绑定函数的默认值,继承二进制函数类的所有类容
class add:public std::binary_function<int ,int,void>
{
public:
    void operator()(int i,int j) const
    {
        std::cout << i + j << endl;
    }
};
void   add(int i, int j)
{
    std::cout << i + j << endl;
}
void mainB()
{
    vector<int> myv;
    myv.push_back(11);
    myv.push_back(23);
    myv.push_back(34);

    //for_each(myv.begin(), myv.end(), bind1st(add(),10));
    for_each(myv.begin(), myv.end(), boost::bind(add, 13, _1)); 

    //bind设置默认参数调用,函数副本机制,不能拷贝构造
    cin.get();
}

四、Boost::function

1、范例:

#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <vector>
#include <algorithm>
#include <functional>
#include <stdlib.h>
using namespace std;
using namespace boost;

void mainC()
{
    //atoi  //char * to  int
    //boost::function<int(char *)> fun = atoi;
    cout << fun("123") + fun("234") << endl;
    fun = strlen;
    cout << fun("123") + fun("234") << endl;
    cin.get();
}
void mainD()
{
    boost::function<int(char *)> fun = atoi;
    cout << fun("123") + fun("234") << endl;
    fun = boost::bind(strcmp, "ABC", _1);
    cout << fun("123") << endl;
    cout << fun("ABC") << endl;

    cin.get();
}
/*在一个类中调用另外一个类中的函数,*/
class manager
{
public:
    void allstart()
    {
        for (int i = 0; i < 10;i++)
        {
            if (workid)
            {
                workid(i);
            }
        }
    }
    void setcallback(boost::function<void(int)> newid)//绑定调用
    {
        workid = newid;
    }
public:
    boost::function<void(int)> workid;
};
class worker :public std::binary_function<int, int, void>
{
public:
    void run(int toid)
    {
        id = toid;
        cout << id << "工作" << endl;
    }
    void operator ()(int toid,int num)const
    {

        cout << toid + num << "工作" << endl;
    }
public:
    int id;

};
void   add1(int i, int j)
{
    std::cout << i + j << endl;

}
void main()
{
    manager m;
    worker w;

    vector<int> myv;
    myv.push_back(11);
    myv.push_back(23);
    myv.push_back(34);
    for_each(myv.begin(), myv.end(), bind(add1, 113, _1));
    //类的成员函数需要对象来调用,绑定了一个默认的对象
    m.setcallback(boost::bind(&worker::run, &w, _1));
    m.allstart();
    //m.setcallback(boost::bind(worker(),113,_1));
    //m.allstart();
    //for_each(myv.begin(), myv.end(), bind(&worker::run, &w, 113, _1));
    for_each(myv.begin(), myv.end(), boost::bind(worker(), 113, _1));

    cin.get();
}

五、Boost::ref 和 boost::cref

1、介绍:
①.库ref在boost/ref.hpp中提供了模板工厂函boost::ref,boost::cref分别对应包装引用和常引用。
②.当在某些情况下需要拷贝对象参数,如果该对象无法进行拷贝,或者拷贝代价过高,这时候就可以选择ref。
2、范例:

#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <vector>
#include <algorithm>
#include <functional>
#include <stdlib.h>
using namespace std;
using namespace boost;

void print(std::ostream &os,int i)
{
    os << i << endl;
}
void mainF()
{
    //不可以拷贝的对象可以用ref
    boost::function<void(int)> pt = boost::bind(print,boost::ref(cout), _1);
    vector<int > v;
    v.push_back(11);
    v.push_back(12);
    v.push_back(13);
    for_each(v.begin(), v.end(), pt);

    std::cin.get();
}

六、C++ RAII 资源获取即初始化

1、简介:
①.RAII是resource acquisition is initialization的缩写,意为“资源获取即初始化”。它是C++之父Bjarne Stroustrup提出的设计理念,其核心是把资源和对象的生命周期绑定,对象创建获取资源,对象销毁释放资源。在RAII的指导下,C++把底层的资源管理问题提升到了对象生命周期管理的更高层次。
②.说起来,RAII的含义倒也不算复杂。用白话说就是:在类的构造函数中分配资源,在析构函数中释放资源。这样,当一个对象创建的时候,构造函数会自动地被调用;而当这个对象被释放的时候,析构函数也会被自动调用。于是乎,一个对象的生命期结束后将会不再占用资源,资源的使用是安全可靠的。
2、特点:
①.C++ RAII体现出了简洁、安全、实时的特点:
②.1.概念简洁性:让资源(包括内存和非内存资源)和对象的生命周期绑定,资源类的设计者只需用在类定义内部处理资源问题,提高了程序的可维护性;
③.2.类型安全性:通过资源代理对象包装资源(指针变量),并利用运算符重载提供指针运算方便使用,但对外暴露类型安全的接口;
④.3.异常安全性:栈语义保证对象析构函数的调用,提高了程序的健壮性;
⑤.4.释放实时性:和GC相比,RAII达到了和手动释放资源一样的实时性,因此可以承担底层开发的重任。
3、范例:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;

class mystr
{
public:
    char *p = nullptr;
public:
    mystr(const char *str)
    {
        int length = strlen(str);
        p = new char[length + 1];
        strcpy(p, str);
        p[length] = '\0';
    }
    ~mystr()
    {
        cout << "销毁" << endl;
        delete[] p;
    }
};
void go()
{
    char *p = new char[100];
    mystr str1 = "ABCD";//RAII避免内存泄漏,一般情况下,堆上的内存当作栈上来使用
    //栈内存有限,希望自动释放,用很大的内存。
}
void mainHG()
{
    go();
    cin.get();
}

七、Std::auto_ptr ——智能指针

1、介绍:
①.智能指针就是RAII中相当典型的一例,它很好的体现了RAII的理念,自动获取释放;
2、范例:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <stdlib.h>
using namespace std;

template<class T>
class pmy
{
public:
    pmy()
    {   }
    pmy(T *t)
    {
        p = t;
    }
    ~pmy()
    {
       if (p!=nullptr)
       {
           delete p ;
           P = nullptr ;
       }
    }
    T operator *()
    {
        return *p;
    }
private:
    T *p=nullptr;
};
class Test
{
public:
    Test()
    {
        cout << "Test  create" << endl;
    }
    ~Test()
    {
        cout << "Test delete" << endl;
    }
};
void run()
{
    pmy<Test> p(new Test);//智能指针,智能释放
}
void mainH()
{
    run();
    cin.get();
}

八、Boost::scoped_ptr作用域指针

1、简介:
①.相同点:两者都是智能指针,自动释放内存。机理都是重载了*,->运算符,代理指针功能。在构造和系析构中自动创建和释放资源;
②.不同点:std::auto_ptr 所有权可以转让, 而boost::scoped_ptr所有权不可以转让;
③.std::auto_ptr 实现原理比boost::scoped_ptr简单,在所有权不用转让的情况下,优先考虑boost::scoped_ptr ;
2、范例:

#include <iostream>
#include <vector>
#include<algorithm>
#include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/shared_array.hpp>
#include<boost/weak_ptr.hpp>
#include <windows.h>
using namespace std;

void mainI()
{
    boost::scoped_ptr<int> p(new int);//自动释放内存
    *p = 12;
    cout << *p.get() << endl; //获取指针指向的内容
    p.reset(new int);//指针自动释放
    *p.get() = 3;
    boost::scoped_ptr<int> pA(nullptr);
//独占内存,不能将内存共享给其他人
    //pA = p;
    cout << *p.get() << endl;

    cin.get();
}
/*boost::scoped_array作用域数组,独享内存,自动释放内存*/
void mainG()
{
    boost::scoped_array<int> p(new int[10]);//自动释放内存
    //boost::scoped_array<int> pA(p);不行,因为独享指针
    *p.get() = 1;
    p[3] = 2;
    p.reset(new int[5]);//只能指针

    cin.get();
}
/*boost::shared_ptr共享指针*/
void show(boost::shared_ptr<int> p)
{
    cout << *p << endl;
}
void  mainK()
{
    vector<boost::shared_ptr<int> > v;
    boost::shared_ptr<int> p1(new int(11));
    boost::shared_ptr<int> p2(new int(12));
    boost::shared_ptr<int> p3(p2);//拷贝
    v.push_back(p1);
    v.push_back(p2);
    v.push_back(p3);
    for_each(v.begin(), v.end(), show);

    cin.get();
}
/*共享指针在类中的作用*/
class runclass
{
public:
    int  i = 0;
public:
    runclass(int num) :i(num)
    {
        cout << "i create" <<i<< endl;
    }
    runclass() 
    {
        cout << "i create" << i << endl;
    }
    ~runclass()
    {
        cout << "i delete" <<i<< endl;
    }
    void print()
    {
        cout << "i =" << i<<endl;
    }
};
void testfun()
{
    boost::shared_ptr<runclass>  p1(new runclass(10));
    boost::shared_ptr<runclass>  p2(p1);
    boost::shared_ptr<runclass>  p3(p1);
    p1.reset(new runclass(12));
    p1->print(); //12
    p2->print(); //10
    p3->print(); //10
}
/*boost::shared_array共享指针数组*/
void  testfunarray()
{
    boost::shared_array<runclass> p1(new runclass[5]);
    boost::shared_array<runclass> p2(p1);
}
void mainL()
{
    //testfun();
    testfunarray();

    cin.get();
}

/*弱指针*/
DWORD  WINAPI reset(LPVOID p)
{
    boost::shared_ptr<int > *sh = static_cast<boost::shared_ptr<int> *> (p);
    sh->reset();//指针的重置,释放内存
    std::cout << "指针执行释放" << endl;
    return 0;
}
DWORD WINAPI print(LPVOID p)
{
    boost::weak_ptr<int > * pw = static_cast<boost::weak_ptr<int > *>(p);
    boost::shared_ptr<int > sh = pw->lock();//锁定不可以释放
    Sleep(5000);
    if (sh)
    {
        std::cout << *sh << endl;
    }
    else
    {
        std::cout << "指针已经被释放" << endl;
    }
    return 0;
}
void main123()
{
    boost::shared_ptr<int> sh(new int(99));
    boost::weak_ptr<int > pw(sh);
    HANDLE threads[2];
    threads[0] = CreateThread(0, 0, reset, &sh, 0, 0);//创建一个线程
    threads[1] = CreateThread(0, 0, print, &pw, 0, 0);
    Sleep(1000);

    WaitForMultipleObjects(2, threads, TRUE, INFINITE);//等待线程结束
    cin.get();
}

九、Boost::thread

1、范例:

#include <iostream>
#include <vector>
#include<algorithm>
#include<boost/thread.hpp>
#include <windows.h>
using namespace std;
using namespace boost;

void wait(int sec)
{
    boost::this_thread::sleep(boost::posix_time::seconds(sec));
}
void threadA()
{
    for (int i = 0; i < 10;i++)
    {
        wait(1);
        std::cout << i << endl;
    }
}
void threadB()
{
    try
    {
        for (int i = 0; i < 10; i++)
        {
            wait(1);
            std::cout << i << endl;
        }
    }
    catch (boost::thread_interrupted &)
    {
    }
}
void mainO()
{
    boost::thread t(threadA );
    //boost::thread t(threadB );
    wait(3);
    t.interrupt();//结束线程
    t.join();
    cin.get();
}

十、Boost::unordered

1、范例:

#include <iostream>
#include<boost/unordered_set.hpp>
#include<string>
using namespace std;

void mainAAAC()
{
    boost::unordered_set<std::string> myhashset;
    myhashset.insert("ABC");
    myhashset.insert("ABCA");
    myhashset.insert("ABCAG");

    for (auto ib = myhashset.begin(); ib != myhashset.end();ib++)
    {
        cout << *ib << endl;
    }
    std::cout << (myhashset.find("ABCA1") != myhashset.end()) << endl;

    cin.get();
}

十一、Boost::regex 正则

1、简介:
    ①.这部分包含了boost.regex库的正则表达式的语法。这是一份程序员指南,实际的语法由在程序中的正则表达式的选项决定。(译注:即regex类构造函数的flag参数。
2、特殊字符介绍
    ①.除了以下字符,其它的任何字符都表示其字面意义(literal)。

    “.”, “ | ”, “*”, “ ? ”, “ + ”, “(“, “)”, “{ “, “ }”, “[“, “]”, “^”, “$” 和 “\”

    ②.要使用这些字符的字面意义,要在前面使用 “\” 字符。一个字面意义的字符匹配其本身,或者匹配 traits_type::translate() 的结果,这里的traits_type 是 basic_regex
3、类的特性模板参数(the traits template parameter)。
    ①.“.”通配符(Wildcard)
    点号 ”.” 匹配任意的单个字符。当在匹配算法中使用了 match_not_dot_null 选项,那么点号不匹配空字符(null character)。当在匹配算法中使用了 match_not_dot_newline选项,那么点号不匹配换行字符(newline character)。
    ②.“*”“+”重复(Repeats)
        1、“*”:
一个重复是一个表达式(译注:正则表达式)重复任意次数。一个表达式后接一个 “*” 表示重复任意次数(包括0次)。
        2、“+”:
一个表达式后接一个 “ + ” 表示重复任意次数(但是至少1次)。如果表达式使用 regex_constants::bk_plus_qm编译(译注:regex类构造函数的flag参数),那么 “ + ” 是一个普通的字符(译注:即 “ + ” 表示其字面意义), “\ + ” 用来表示重复一或多次。
        3、“?”:
一个表达式后接一个 “ ? ” 表示重复0或1次。如果表达式使用 regex_constants::bk_plus_qm 选项,那么 “ ? ” 是一个普通字符,”\ ? ” 用来表/示重复0或1次。
        4、“{}”:
如果需要显式的指定重复的最大最小次数的话,请使用边界操作符 “{}”,那么 “a{ 2 }” 表示字母 “a” 重复2次, “a{ 2, 4 }” 表示字母 “a” 重复2至4次, “a{ 2, }” 表示字母 “a” 重复至少2次(无上限)。注意:在{}之间是没有任何空格的,并且上下边界的大小是没有上限的。如果表达式使用 regex_constants::bk_braces选项编译,那么 “{ ” 和 “ }” 是普通字符, “\{” 和 “\}” 用来表示边界操作符。
        5、所有的重复表达式是最短的前置子串(the shortest possible previous sub -expression):单个字符,字符集合,或者是用诸如 “()” 括起来的子表达式。例:
“ba*” 匹配 “b”, “ba”, “baaa” 等等。
“ba + ” 匹配诸如 “ba”, “baaaa” 此类,而不匹配 “b”。
“ba ? ” 匹配 “b” 或 “ba”。
“ba{ 2, 4 }” 匹配 “baa”, “baaa” 和 “baaaa”。
        6、非“贪心”重复(Non - greedy repeats)
无论是否启用“扩展(extended)”正则表达式语法(默认的),总是允许使用非贪心重复,只要在重复的后面加一个 “ ? ” 。非贪心重复是匹配最短可能串(the shortest possible string)的重复。例如:
要匹配html的一对标签,可以使用:
“<\s*tagname[^>] * > (.* ? ) < \s* / tagname\s* > ”
这里$1会包含标签之间的文本,这段文本是最短匹配的字符串。
    ③.“()”圆括号(Parenthesis)
圆括号有两个作用组成子表达式和标记匹配(to group items together into a sub - expression, and to mark what generated the match.)。例如,表达式 “(ab)*” 匹配所有的 “ababab”字符串。
匹配算法 regex_match 和 regex_search 各需要一个match_results对象来报告是怎样匹配的,函数返回后match_results会包含整个表达式和各个子表达式的匹配。比如在上述的例子中,match_results[1]会包含表示最后一个 “ab” 的迭代器对(pair)。子表达式也允许匹配空串。如果子表达式匹配为空 - 例如子表达式为选择中的不匹配的那一部分 – 那么一对迭代器指向输入字符串的结尾,并且这个子表达式的matched属性为false。子表达式从左向右,从1开始索引,子表达式0是整个表达式。(译注:上述表达式或子表达式都是指正则表达式。)非标记圆括号(Non - Marking Parenthesis)
有时你需要使用圆括号组成一个子表达式,但是不像要产生一个标记的子表达式(译注:在match_results中的表达式都是标记的子表达式)。在这种情况下,非标记圆括号
(? : expression) 可以使用。例如下列表达式不产生子表达式:
“(? : abc)*”
    ④.前看断言(Forward Lookahead Asserts)
这有两种形式:一个是正的前看断言;一个是负的前看断言:
“(? = abc)” 匹配0个字符,除非表达式以 “abc” 开头。
“(? !abc)” 匹配0个字符,除非表达式不以 “abc” 开头。
(译注:断言并不匹配,例如: “(? = abc)abcdef” 匹配 “abcdef” ,前面的 “(? = abc)” 并不匹配 “abc” ,而是查看是否已abc开头,如果需要匹配 “abc” 还是需要在后面写上的。)独立子表达式(Independent sub - expressions)“(? > expression)” 匹配 “expression” 作为一个独立的原子动作(除非产生错误,算法不会回退产看)。
    ⑤.“|”选择(Alternatives)
选择出现在需要匹配一个子表达式或另一个子表达式的情况下。每个选择的项目使用 “ | ” 分割,或者当设置了 regex_constants::bk_vbar 选项的时候,使用 “\ | ” 分割,或者当设置了 regex_constants::newline_alt 选项的时候,使用换行符分割。每个选择的项目总是最长可能的子表达式,这和重复操作符的情况相反。
例:
“a(b | c)” 匹配 “ab” 或 “ac”。
“abc | def” 匹配
    ⑥.集合(Sets)
集合是一个字符的集合,它能够匹配任意是其成员的字符。集合使用 “[” 和 “]” 来包含文字,字符范围,字符类,对照元素和等值类。使用 “^” 开头的集合表示补集。
例:
字符文字:
"[abc]" 匹配 "a", "b", 或 "c"。
"[^abc] 匹配除 "a", "b", 和 "c" 之外的任何字符。
    ⑦.字符范围:
"[a-z]" 匹配任意在 "a" 至 "z" 之间的字符。
"[^A-Z]" 匹配在 "A" 至 "Z" 之外的字符。
注意,如果设置 regex_constants::collate 选项,那么字符范围的依赖于地域的(locale dependent):它们匹配任意在范围两端之间的字符,当使用默认的 “C” locale 的时候,范围遵循ASCII的规则。例如,如果库是使用Win32地域模型编译的话,那么[a - z] 会匹配 a - z的ASCII字符和 ‘A’, ’B’ 等,但不匹配 ‘Z’ ,它正好在’z’的后面。
默认情况下,地域特殊化的行为的禁止的,范围的比较遵循ASCII字符的编码。
    ⑧.字符类:
字符类是使用 “[:classname : ]” 语法声明的集合。例如 “[[:space : ]]” 是所有空白字符的集合。只有当设置了 regex_constants::char_classes 选项后,字符类才有效。可用的字符类有:
alnum
任何字符数字
alpha
a - z和A - Z之间的字母。如果设置了地域的话,可能包含其它字
blank
任何空白字符,空格或者tab字符。
cntrl
任何控制字符
digit
任何0 - 9之间的数字
graph
任何图形字符
lower
a - z之间的小写字符。如果设置了地域的话,可能包含其它字符。
print
任何可打印字符
punct
任何标点符号
space
任何空格字符
upper
A - Z之间的大写字母。如果设置了地域的话,可能包含其它字符。
xdigit
任何在0 - 9, a - f和A - F之间的16进制数字
word
任何单词字符 – 字母数字加上下划线
Unicode
任何编码大于255的字符,只能在宽字符中使用
当设置了 regex_constants::escape_in_lists 选项后,你可以使用一些字符类的缩写:
\w 代替[:word : ]
\s代替[:space : ]
\d代替[:digit : ]
\l代替[:lower : ]
\u代替[:upper : ]
对照元素(Collating elements)是集合声明中的通过[.tagname.] 表示,此处 tagname 是单个字符或者是对照元素的名称。例如[[.a.]] 相当于[a] ,[[.comma.]] 相当于
[, ] 。库支持所有标准POSIX的对照元素名称和下列额外的名称: “ae”, “ch”, “ll”, “ss”, “nj”, “dz”, “lj” ,每个都可以小写,大写或开头大写。多字符对照
元素令集合匹配一个以上的字符,例如[[.ae.]]匹配两个字符,而[^[.ae.]]只匹配一个字符。
Equivalence classes take the generalform[=tagname=] inside a set declaration, where tagname is either a single character, or a name of a collating element,and matches any character that is a member of the same primary equivalence class as the collating element[.tagname.].An equivalence class is a set of characters that collate the same, a primary equivalence class is a set of characters whose primary sort key are all the same(for example strings are typically collated by character, then by accent, and then by case; the primary sort key then relates to the character, the secondary to the accentation, and the tertiary to the case).If there is no equivalence class corresponding to tagname, then[=tagname=] is exactly the same as[.tagname.].Unfortunately there is no locale independent method of obtaining the primary sort key for a character, except under Win32.For other operating systems the library will "guess" the primary sort key from the full sort key(obtained from strxfrm), so equivalence classes are probably best considered broken under any operating system other than Win32.
To include a literal "-" in a set declaration then : make it the first character after the opening "[" or "[^", the endpoint of a range, a collating element,or if the flag regex_constants::escape_in_lists is set then precede with an escape character as in "[\-]".To include a literal "[" or "]" or "^" in a set then make them the endpoint of a range, a collating element, or precede with an escape character if the flag regex_constants::escape_in_lists is set.
⑨.“^” “$”行锚(Line anchors)
锚(anchor)是用来在一行开头或结尾匹配空串的: “^” 在一行的开头匹配空串, “$” 匹配行尾的空串。
⑩.回退引用(Back references)
回退引用是对已经匹配的子表达式的引用,这个引用是子表达式匹配的字符串,而不是子表达式本身。回退引用由换码符 “\” 加一个 “1” 到 “9” 的数字组成, “\1” 引用第一个子表达式, “\2” 引用第二个 等等。 例如表达式 “(.*)\1” 匹配任何重复2次的字符串,比如 “abcabc” 或 “xyzxyz”。子表达式的回退引用不参与任何匹配,匹配空串:NB 这不同于其它一般性的正则式匹配。只有使用了 regex_constants : bk_refs 选项才能使用回退引用。
⑪.编码的字符(Characters by code)
这是算法的一个扩展,在其它的库中是没有的。它由换码符加数字 “0” 加 10进制的字符编码组成。例如 “\023” 表示10进制编码是23的字符。当使用圆括号分割了表达式时,可能引起模糊: “\0103” 表示103编码的字符, “(\010)3” 表示字符10接着一个 “3”。要使用16进制编码的话,用 \x 加一个16进制数就可以了,可以使用{} 括起来,
例如 \xf0 或 \x{ aff } ,注意后一个例子是一个Unicode字符。
⑫.单词操作符(Word operators)
下列操作符提供了与GNU正则式库德兼容。
“\w” 匹配任何属于 “word” 类的字符,相当于 “[[:word : ]]”。
“\W” 匹配任何不属于 “word” 类的字符,相当于 “[^[:word : ]]”。
“\<” 匹配一个单词开头的空串。
“\>” 匹配一个单词结尾的空串。
“\b” 匹配单词开头或结尾的空串。
“\B” 匹配单词内的空串。
The start of the sequence passed to the matching algorithms is considered to be a potential start of a word unless the flag match_not_bow is set.The end of the sequence passed to the matching algorithms is considered to be a potential end of a word unless the flag match_not_eow is set.
⑬.缓冲操作符(Buffer operators)
下列操作符提供了与GNU正则式库和Perl正则式库的兼容:
“\`” 匹配一个缓冲的开头(the start of a buffer)。
“\A” 匹配缓冲的开头(the start of the buffer)。
“\’” 匹配缓冲的结尾。
“\z” 匹配缓冲的结尾。
“\Z” 匹配缓冲的结尾,可能包含一或多个换行符。
一个缓冲是提供给匹配算法的整个序列,除非设置了 match_not_bob 或 match_not_eob 选项。
⑭.换码操作符(Escape operator)
换码字符 “\” 有好几个意思。
在集合声明内,换码符是一个普通的字符,除非设置了 regex_constants::escape_in_lists 选项,此时 “\” 之后的字符表示其字面意义而不考虑其原来的意思.
换码符可以引出其它的操作,例如:回退引用,或单词操作符。
换码符可以接一个正常的字符,例如 “\*” 表示一个字面意义的 “*” 而不是重复操作符。
单字符换码串(Single character escape sequences)
下列是单个字符的换码串:
换码串
字符编码
含义
\a
0x07
Bell character.
\f
0x0C
Form feed.
\n
0x0A
Newline character.
\r
0x0D
Carriage return.
\t
0x09
Tab character.
\v
0x0B
Vertical tab.
\e
0x1B
ASCII Escape character.
\0dd
0dd
An octal character code, where dd is one or more octal digits.
\xXX
0xXX
A hexadecimal character code, where XX is one or more hexadecimal digits.
\x{ XX }
0xXX
A hexadecimal character code, where XX is one or more hexadecimal digits, optionally a Unicode character.
\cZ
z - @
An ASCII escape sequence control - Z, where Z is any ASCII character greater than or equal to the character code for '@'.
各种换码串:
下列提供了和perl的兼容,但注意 \1 \L \u和\U的不同之处:
\w  相当于[[:word : ]]。
\W  相当于[^[:word : ]]。
\s  相当于[[:space : ]]。
\S  相当于[^[:space : ]]。
/\d  相当于[[:digit : ]]。
\D  相当于[^[:digit : ]]。
\l  相当于[[:lower : ]]。
\L  相当于[^[:lower : ]]。
\u  相当于[[:upper : ]]。
\U  相当于[^[:upper : ]]。
\C  任何字符,相当于'.'。
\X  匹配任何Unicode组和字符串,例如"a\x 0301" (带重音号的字符)。
\Q  开始引用操作符,任何后面的字符被认为是字面意义,除非是\E 结束引用操作符的出现。
\E  结束引用操作符, 终止\Q开始的序列。
What gets matched ?
When the expression is compiled as a Perl - compatible regex then the matching algorithms will perform a depth first search on the state machine and report the first match found.
When the expression is compiled as a POSIX - compatible regex then the matching algorithms will match the first possible matching string, if more than one string starting at a given location can match then it matches the longest possible string, unless the flag match_any is set, in which case the first match encountered is returned.Use of the match_any option can reduce the time taken to find the match - but is only useful if the user is less concerned about what matched - for example it would not be suitable for search and replace operations.In cases where their are multiple possible matches all starting at the same location, and all of the same length, then the match chosen is the one with the longest first sub - expression, if that is the same for two or more matches, then the second sub - expression will be examined and so on.
The following table examples illustrate the main differences between Perl and POSIX regular expression matching rules :
⑮.表达式
文本
POSIX最左长匹配
ECMAScript深度优先搜索匹配
a | ab
xaby
“ab”
“a”
.*([[:alnum : ]] + ).*
" abc def xyz "
$0 = " abc def xyz "
$1 = "abc"
$0 = " abc def xyz "
$1 = "z"
.*(a | xayy)
zzxayyzz
"zzxayy"
"zzxa"
These differences between Perl matching rules, and POSIX matching rules, mean that these two regular expression syntaxes differ not only in the features offered, but also in the form that the state machine takes and / or the algorithms used to traverse the state machine.

4、范例:

#include <boost/regex.hpp>
#include <locale>
#include <iostream>
#include <string>
using namespace std;

void mainA123()
{
    std::locale::global(std::locale("English"));
    string  str = "chinaen8Glish";
    boost::regex  expr("\\w+\\d\\u\\w+");//d代表数字,
    //匹配就是1,不匹配就是0
    cout << boost::regex_match(str, expr) << endl;

    cin.get();
}
void mainB123()
{
    std::locale::global(std::locale("English"));
    string  str = "chinaen8Glish9abv";
    boost::regex  expr("(\\w+)\\d(\\w+)");//d代表数字,
    boost::smatch  what;
    if (boost::regex_search(str,what,expr))//按照表达式检索
    {
        cout << what[0] << endl;
        cout << what[1] << endl;
    }
    else    {
        cout << "检索失败";
    }
    cin.get();
}
void   mainC1234()
{
    string  str = "chinaen8  Glish9abv";
    boost::regex  expr("\\d");//d代表数字,
    string  kongge = "______";
    std::cout << boost::regex_replace(str, expr, kongge) << endl;
    cin.get();
}
【为什么还需要学习C++?】 你是否接触很多语言,但从来没有了解过编程语言的本质?你是否想成为一名资深开发人员,想开发别人做不了的高性能程序?你是否经常想要窥探大型企业级开发工程的思路,但苦于没有基础只能望洋兴叹? 那么C++就是你个人能力提升,职业之路进阶的不二之选。【课程特色】 1.课程共19大章节,239课时内容,涵盖数据结构、函数、类、指针、标准库全部知识体系。2.带你从知识与思想的层面从0构建C++知识框架,分析大型项目实践思路,为你打下坚实的基础。3.李宁老师结合4大国外顶级C++著作的精华为大家推出的《征服C++11》课程。【学完后我将达到什么水平?】 1.对C++的各个知识能够熟练配置、开发、部署;2.吊打一切关于C++的笔试面试题;3.面向物联网的“嵌入式”和面向大型化的“分布式”开发,掌握职业钥匙,把握行业先机。【面向人群】 1.希望一站式快速入门的C++初学者; 2.希望快速学习 C++、掌握编程要义、修炼内功的开发者; 3.有志于挑战更高级的开发项目,成为资深开发的工程师。 【课程设计】 本课程包含3大模块基础篇本篇主要讲解c++的基础概念,包含数据类型、运算符等基本语法,数组、指针、字符串等基本词法,循环、函数、类等基本句法等。进阶篇本篇主要讲解编程中常用的一些技能,包含类的高级技术、类的继承、编译链接和命名空间等。提升篇:本篇可以帮助学员更加高效的进行c++开发,其中包含类型转换、文件操作、异常处理、代码重用等内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值