classbasic_regex{public:explicitbasic_regex(constcharT*p,fl" />
当前位置:文档之家› boost库中的正则表达式

boost库中的正则表达式

boost库中的正则表达式
boost库中的正则表达式

Regex 头文件: "boost/regex.hpp"

正则表达式被封装为一个类型basic_regex的对象。我们将在下一节更深入地讨论正则表达式如何被编译和分析,这里我们首先粗略地看看basic_regex ,以及这个库中三个最重要的算法。

namespace boost { template > class basic_regex { public: explicit basic_regex( const charT* p, flag_type f=regex_constants::normal); bool empty() const; unsigned mark_count() const; flag_type flags() const; }; typedef basic_regex regex; typedef basic_regex wregex; } 成员函数explicit basic_regex ( const charT* p,

flag_type f=regex_constants::normal);

这个构造函数接受一个包含正则表达式的字符序列,还有一个参数用于指定使用正则表达式时的选项,例如是否忽略大小写。如果p中的正则表达式无效,则抛出一个bad_expression 或regex_error 的异常。注意这两个异常其实是同一个东西;在写这本书之时,尚未改变当前使用的名字bad_expression ,但下一个版本的Boost.Regex将会使用regex_error.

bool empty() const;

这个成员函数是一个谓词,当basic_regex实例没有包含一个有效的正则表达式时返回

true ,即它被赋予一个空的字符序列时。

unsigned mark_count() const;

mark_count 返回regex中带标记子表达式的数量。带标记子表达式是指正则表达式中用圆括号括起来的部分。匹配这个子表达式的文本可以通过调用某个正则表达式算法而获得。

flag_type flags() const;

返回一个位掩码,其中包含这个basic_regex所设置的选项标志。例如标志icase, 表示正则表达式忽略大小写,标志JavaScript, 表示regex使用JavaScript的语法。

typedef basic_regex regex; typedef basic_regex wregex;

不要使用类型basic_regex来定义变量,你应该使用这两个typedef中的一个。这两个类型,regex 和wregex, 是两种字符类型的缩写,就如string 和wstring 是basic_string

basic_string的缩写一样。这种相似性是不一样的,某种程度上,regex 是一个特定类型的字符串的容器。

普通函数template bool regex_match( const charT* str, match_results& m, const basic_regex& e,

match_flag_type flags = match_default);

regex_match 判断一个正则表达式(参数e)是否匹配整个字符序列str. 它主要用于验证文本。注意,这个正则表达式必须匹配被分析串的全部,否则函数返回false. 如果整个序列被成功匹配,regex_match 返回True.

template bool regex_search( const charT* str,

match_results& m, const basic_regex& e,

match_flag_type flags = match_default);

regex_search 类似于regex_match, 但它不要求整个字符序列完全匹配。你可以用

regex_search 来查找输入中的一个子序列,该子序列匹配正则表达式e.

template basic_string regex_replace( const

basic_string& s, const basic_regex& e, const basic_string& fmt, match_flag_type flags = match_default);

regex_replace 在整个字符序列中查找正则表达式e的所有匹配。这个算法每次成功匹配后,就根据参数fmt对匹配字符串进行格式化。缺省情况下,不匹配的文本不会被修改,即文本会被输出但没有改变。

这三个算法都有几个不同的重载形式:一个接受const charT* (charT 为字符类型), 另一个接受const basic_string&, 还有一个重载接受两个双向迭代器作为输入参数。

用法

要使用Boost.Regex, 你需要包含头文件"boost/regex.hpp". Regex是本书中两个需要独立编译的库之一(另一个是Boost.Signals)。你会很高兴获知如果你已经构建了Boost——那只需在命令提示符下打一行命令——就可以自动链接了(对于Windows下的编译器),所以你不需要为指出那些库文件要用而费心。

你要做的第一件事就是声明一个类型basic_regex 的变量。这是该库的核心类之一,也是存放正则表达式的地方。创建这样一个变量很简单;只要将一个含有你要用的正则表达式的字符串传递给构造函数就行了。

boost::regex reg("(A.*)");

这个正则表达式具有三个有趣的特性。第一个是,用圆括号把一个子表达式括起来,这样可以稍后在同一个正则表达式中引用它,或者取出匹配它的文本。我们稍后会详细讨论它,所以如果你还不知道它有什么用也不必担心。第二个是,通配符(wildcard)字符,点。这个通配符在正则表达式中有非常特殊的意义;这可以匹配任意字符。最后一个是,这个表达式用到了一个重复符,*, 称为Kleene star, 表示它前面的表达式可以被匹配零次或多次。这个正则表达式已可以用于某个算法了,如下:

bool b=boost::regex_match( "This expression could match from A and beyond.", reg);

如你所见,你把正则表达式和要分析的字符串传递给算法regex_match. 如果的确存在与正则表达式的匹配,则该函数调用返回结果true ;否则,返回false. 在这个例子中,结果是false, 因为regex_match 仅当整个输入数据被正则表达式成功匹配时才返回true 。你知道为什么是这样吗?再看一下那个正则表达式。第一个字符是大写的A, 很明显能够匹配这个表达式的第一个字符在哪。所以,输入的一部分"A and beyond."可以匹配这个表达式,但这不是整个输入。让我们试一下另一个输入字符串。

bool b=boost::regex_match( "As this string starts with A, does it match? ", reg);

这一次,regex_match 返回true. 当正则表达式引擎匹配了A, 它接着看后续有什么。在我们的regex变量中,A 后跟一个通配符和一个Kleene star, 这意味着任意字符可以被匹配任意次。因而,分析过程开始扔掉输入字符串的剩余部分,即匹配了输入的所有部分。

接下来,我们看看如何使用regexes 和regex_match 来进行数据验证。

验证输入

正则表达式常用于对输入数据的格式进行验证。应用软件通常要求输入符合某种结构。考虑一个应用软件,它要求输入一定要符合如下格式,"3个数字, 一个单词, 任意字符, 2个数字或字符串"N/A," 一个空格, 然后重复第一个单词." 手工编写代码来验证这个输入既沉闷又

容易出错,而且这些格式还很可能会改变;在你弄明白之前,可能就需要支持其它的格式,你精心编写的分析器可能就需要修改并重新调试。让我们写出一个可以验证这个输入的正则表达式。首先,我们需要一个匹配3个数字的表达式。对于数字,我们应该使用一个特别的缩写,\d。要表示它被重复3次,需要一个称为bounds operator的特定重复,它用花括号括起来。把这两个合起来,就是我们的正则表达式的开始部分了。

boost::regex reg("\\d{3}");

注意,我们需要在转义字符(\)之前加一个转义字符,即在我们的字符串中,缩写\d 变成了\\d 。这是因为编译器会把第一个\当成转义字符扔掉;我们需要对\进行转义,这样\才可以出现在我们的正则表达式中。

接下来,我们需要定义一个单词的方法,即定义一个字符序列,该序列结束于一个非字母字符。有不只一种方法可以实现它,我们将使用字符类别(也称为字符集)和范围这两个正则表达式的特性来做。字符类别即一个用方括号括起来的表达式。例如,一个匹配字符a, b, 和c 中任一个的字符类别表示为:[abc]. 如果用范围来表示同样的东西,我们要写:[a-c]. 要写一个包含所有字母的字符类型,我们可能会有点发疯,如果要把它写成:[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ], 但不用这样;我们可以用范围来表示:[a-zA-Z]. 要注意的是,象这样使用范围要依赖于当前所用的locale,如果正则表达式的basic_regex::collate 标志被打开。使用以上工具以及重复符+, 它表示前面的表达式可以重复,但至少重复一次,我们现在可以表示一个单词了。

boost::regex reg("[a-zA-Z]+");

以上正则表达式可以工作,但由于经常要表示一个单词,所以有一个更简单的方法:\w. 这个符号匹配所有单词,不仅是ASCII的单词,因此它不仅更短,而且也更适用于国际化的环境。接下来的字符是一个任意字符,我们已经知道要用点来表示。

boost::regex reg(".");

再接下来是2个数字或字符串"N/A." 为了匹配它,我们需要用到一个称为选择的特性。选择即是匹配两个或更多子表达式中的任意一个,每种选择之间用| 分隔开。就象这样:boost::regex reg("(\\d{2}|N/A)");

注意,这个表达式被圆括号括了起来,以确保整个表达式被看作为两个选择。在正则表达式中增加一个空格是很简单的;用缩写\s. 把以上每一样东西合并起来,就得到了以下表达式:boost::regex reg("\\d{3}[a-zA-Z]+.(\\d{2}|N/A)\\s");

现在事情变得有点复杂了。我们需要某种方法,来验证接下来的输入数据中的单词是否匹配第一个单词(即那个我们用表达式[a-zA-Z]+所捕获的单词)。关键是要使用后向引用(back reference),即对前面的子表达式的引用。为了可以引用表达式[a-zA-Z]+, 我们必须先把它用圆括号括起来。这使得表达式([a-zA-Z]+)成为我们的正则表达式中的第一个子表达式,我们就可以用索引1来建立一个后向引用了。

这样,我们就得到了整个正则表达式,用于表示"3个数字, 一个单词, 任意字符, 2个数字或字符串"N/A," 一个空格, 然后重复第一个单词.":

boost::regex reg("\\d{3}([a-zA-Z]+).(\\d{2}|N/A)\\s\\1");

干的好!下面是一个简单的程序,把这个表达式用于算法regex_match, 验证两个输入字符串。

#include #include #include #include "boost/regex.hpp" int main() { // 3 digits, a word, any character, 2 digits or "N/A", // a space, then the first word again boost::regex reg("\\d{3}([a-zA-Z]+).(\\d{2}|N/A)\\s\\1"); std::string correct="123Hello N/A Hello"; std::string incorrect="123Hello 12 hello"; assert(boost::regex_match(correct,reg)==true); assert(boost::regex_match(incorrect,reg)==false); }

第一个字符串,123Hello N/A Hello, 是正确的;123 是3个数字,Hello 是一个后跟任意字符(一个空格)的单词,然后是N/A和另一个空格,最后重复单词Hello 。第二个字符串是不正确的,因为单词Hello 没有被严格重复。缺省情况下,正则表达式是大小写敏感的,因而反向引用不能匹配。

写出正则表达式的一个关键是成功地分解问题。看一下你刚才建立的最终的那个表达式,对于未经过训练的人来说它的确很难懂。但是,如果把这个表达式分解成小的部分,它就不太复杂了。

查找

现在我们来看一下另一个Boost.Regex算法, regex_search. 与regex_match 不同的是,regex_search 不要求整个输入数据完全匹配,则仅要求部分数据可以匹配。作为说明,考虑一个程序员的问题,他可能在他的程序中有一至两次忘记了调用delete 。虽然他知道这个简单的测试可能没什么意义,他还是决定计算一下new 和delete出现的次数,看看数字是否符合。这个正则表达式很简单;我们有两个选择,new 和delete.

boost::regex reg("(new)|(delete)");

有两个原因我们要把子表达式用括号括起来:一个是为了表明我们的选择是两个组。另一个原因是我们想在调用regex_search时引用这些子表达式,这样我们就可以判断是哪一个选择被匹配了。我们使用regex_search的一个重载,它接受一个match_results类型的参数。当regex_search 执行匹配时,它通过一个match_results类型的对象报告匹配的子表达式。类模板match_results 使用一个输入序列所用的迭代器类型来参数化。

template > class match_results; typedef match_results cmatch; typedef match_results wcmatch; typedef match_results smatch; typedef

match_results wsmatch;

我们将使用std::string, 所以要留意typedef smatch, 它是

match_results的缩写。如果regex_search 返回true, 传递给该函数的match_results 引用将包含匹配的子表达式结果。在match_results里,用已索引的

sub_match来表示正则表达式中的每个子表达式。我们来看一下我们如何帮助这位困惑的程序员来计算对new 和delete的调用。

boost::regex reg("(new)|(delete)"); boost::smatch m; std::string s= "Calls to new must be followed by delete. \ Calling simply new results in a leak!"; if (boost::regex_search(s,m,reg)) { // Did new match? if (m[1].matched) std::cout << "The expression_r(new) matched!\n"; if (m[2].matched) std::cout << "The expression_r(delete) matched!\n"; }

以上程序在输入字符串中查找new 或delete, 并报告哪一个先被找到。通过传递一个类型smatch 的对象给regex_search, 我们可以得知算法如何执行成功的细节。我们的表达式中有两个子表达式,因此我们可以通过match_results的索引1得到子表达式new . 这样我们得

到一个sub_match实例,它有一个Boolean成员,matched, 告诉我们这个子表达式是否参与了匹配。因此,对于上例的输入,运行结果将输出"The expression_r(new) matched!\n". 现在,你还有一些工作要做。你需要继续把正则表达式应用于输入的剩余部分,为此,你要使用另外一个regex_search的重载,它接受两个迭代器,指示出要查找的字符序列。因为std::string 是一个容器,它提供了迭代器。现在,在每一次匹配时,你必须把指示范围起始点的迭代器更新为上一次匹配的结束点。最后,增加两个变量来记录new 和delete的次数。以下是完整的程序:

#include #include #include "boost/regex.hpp" int main() { // "new" and "delete" 出现的次数是否一样?boost::regex reg("(new)|(delete)"); boost::smatch m; std::string s= "Calls to new must be followed by delete. \ Calling simply new results in a leak!"; int

new_counter=0; int delete_counter=0; std::string::const_iterator it=s.begin();

std::string::const_iterator end=s.end(); while (boost::regex_search(it,end,m,reg)) { // 是new 还

是delete? m[1].matched ? ++new_counter : ++delete_counter; it=m[0].second; } if

(new_counter!=delete_counter) std::cout << "Leak detected!\n"; else std::cout << "Seems ok...\n"; }

注意,这个程序总是把迭代器it 设置为m[0].second。match_results[0] 返回对匹配整个正则表达式的子匹配的引用,因此我们可以确认这个匹配的结束点就是下次运行regex_search 的起始点。运行这个程序将输出"Leak detected!", 因为这里有两次new, 而只有一次delete. 当然,一个变量也可能在两个地方删除,还有可能调用new[] 和delete[], 等等。

现在,你应该已经对子表达式如何分组使用有了较好的了解。现在是时候进入到最后一个Boost.Regex算法,该算法用于执行替换工作。

替换

Regex算法家族中的第三个算法是regex_replace. 顾名思义,它是用于执行文本替换的。它在整个输入数据中进行搜索,查找正则表达式的所有匹配。对于表达式的每一个匹配,该算法调用match_results::format 并输入结果到一个传入函数的输出迭代器。

在本章的介绍部分,我给出了一个例子,将英式拼法的colour 替换为美式拼法color. 不使用正则表达式来进行这个拼写更改会非常乏味,也很容易出错。问题是可能存在不同的大小

写,而且会有很多单词被影响,如colourize. 要正确地解决这个问题,我们需要把正则表达式分为三个子表达式。

boost::regex reg("(Colo)(u)(r)", boost::regex::icase|boost::regex::perl);

我们将要去掉的字母u独立开,为了在所有匹配中可以很容易地删掉它。另外,注意到这个正则表达式是大小写无关的,我们要把格式标志boost::regex::icase 传给regex 的构造函数。你还要传递你想要设置的其它标志。设置标志时一个常见的错误就是忽略了regex缺省打开的那些标志,如果你没有设置这些标志,它们不会打开,你必须设置所有你要打开的标志。

调用regex_replace时,我们要以参数方式提供一个格式化字符串。该格式化字符串决定如何进行替换。在这个格式化字符串中,你可以引用匹配的子表达式,这正是我们想要的。你想保留第一个和第三个匹配的子表达式,而去掉第二个(u)。表达式$N表示匹配的子表达式, N 为子表达式索引。因此我们的格式化串应该是"$1$3", 表示替换文本为第一个和第三个子表达式。通过引用匹配的子表达式,我们可以保留匹配文本中的所有大小写,而如果我们用字符串来作替换文本则不能做到这一点。以下是解决这个问题的完整程序。

#include #include #include "boost/regex.hpp" int main() { boost::regex

reg("(Colo)(u)(r)", boost::regex::icase|boost::regex::perl); std::string s="Colour, colours, color, colourize"; s=boost::regex_replace(s,reg,"$1$3"); std::cout << s; }

程序的输出是"Color, colors, color, colorize". regex_replace 对于这样的文本替换非常有用。用户常见的误解

我所见到的与Boost.Regex相关的最常见的问题与regex_match的语义有关。人们很容易忘记必须使regex_match的所有输入匹配给定的正则表达式。因此,用户常以为以下代码会返回true.

boost::regex reg("\\d*"); bool b=boost::regex_match("17 is prime",reg);

无疑这个调用永远不会得到成功的匹配。只有所有输入被regex_match 匹配才可以返回true!几乎所有的用户都会问为什么regex_search 不是这样而regex_match 是。boost::regex reg("\\d*"); bool b=boost::regex_search("17 is prime",reg);

这次肯定返回true. 值得注意的是,你可以用一些特定的缓冲操作符来让regex_search 象regex_match 那样运行。\A 匹配缓冲的起始点,而\Z 匹配缓冲的结束点,因此如果你把\A 放在正则表达式的开始,把\Z 放在最后,你就可以让regex_search 象regex_match 那样使用,即必须匹配所有输入。以下正则表达式要求所有输入被匹配掉,而不管你使用的是regex_match 或是regex_search.

boost::regex reg("\\A\\d*\\Z");

请记住,这并不表示可以无需使用regex_match;相反,它可以清晰地表明我们刚才说到的语义,即必须匹配所有输入。

关于重复和贪婪

另一个容易混淆的地方是关于重复的贪婪。有些重复,如+ 和*,是贪婪的。即是说,它们会消耗掉尽可能多的输入。以下正则表达式并不罕见,它用于在一个贪婪的重复后捕获两个数字。

boost::regex reg("(.*)(\\d{2})");

这个正则表达式是对的,但它可能不能匹配你想要的子表达式!表达式.* 会吞掉所有东西而后续的子表达式将不能匹配。以下是示范这个行为的一个例子:

int main() { boost::regex reg("(.*)(\\d{2})"); boost::cmatch m; const char* text = "Note that I'm 31 years old, not 32."; if(boost::regex_search(text,m, reg)) { if (m[1].matched) std::cout << "(.*) matched: " << m[1].str() << '\n'; if (m[2].matched) std::cout << "Found the age: " << m[2] <<

'\n'; } }

在这个程序中,我们使用了match_results的另一个特化版本,即类型cmatch. 它就是match_results 的typedef, 之所以我们必须用它而不是用之前用过的smatch,是因为我们现在是用一个字符序列调用regex_search 而不是用类型std::string 来调用。你期望这个程序的运行结果是什么?通常,一个刚开始使用正则表达式的用户会首先想到

m[1].matched 和m[2].matched 都为true, 且第二个子表达式的结果会是"31". 接着在认识到贪婪的重复所带来的效果后,即重复会尽可能消耗输入,用户会想到只有第一个子表达式是true,即 .* 成功地吞掉了所有的输入。最后,新用户得到了下结论,两个子表达式都被

匹配,但第二个表达式匹配的是最后一个可能的序列。即第一个子表达式匹配的是"Note that I'm 31 years old, not" 而第二个匹配"32".

那么,如果你想使用重复并匹配另一个子表达式的第一次出现,该怎么办?要使用非贪婪的重复。在重复符后加一个? ,重复就变为非贪婪的了。这意味着该表达式会尝试发现最短的匹配可能而不再阻止表达式的剩余部分进行匹配。因此,要让前面的正则表达式正确工作,我们需要把它改为这样。

boost::regex reg("(.*?)(\\d{2})");

如果我们用这个正则表达式来修改程序,那么m[1].matched 和m[2].matched 都会为true. 表达式.*? 只消耗最少可能的输入,即它将在第一个字符3处停止,因为这就是表达式要成功匹配所需要的。因此,第一个子表达式会匹配"Note that I'm" 而第二个匹配"31".

看一下regex_iterator

我们已经看过如何用几次regex_search 调用来处理所有输入,但另一方面,更为优雅的方法是使用regex_iterator. 这个迭代器类型用一个序列来列举正则表达式的所有匹配。解引用一个regex_iterator 会产生对一个match_results 实例的引用。构造一个regex_iterator 时,你要把指示输入序列的迭代器传给它,并提供相应的正则表达式。我们来看一个例子,输入数据是一组由逗号分隔的整数。相应的正则表达式很简单。

boost::regex reg("(\\d+),?");

在正则表达式的最后加一个? (匹配零次或一次) 确保最后一个数字可以被成功分析,即使输入序列不是以逗号结束。另外,我们还使用了另一个重复符+. 这个重复符表示匹配一次或多次。现在,不需要多次调用regex_search, 我们创建一个regex_iterator, 并调用算法

for_each, 传给它一个函数对象,该函数对象以迭代器的解引用进行调用。下面是一个接受任意形式的match_results的函数对象,它有一个泛型的调用操作符。它所执行的就是把当前匹配的值加到一个总和中(在我们的正则表达式中,第一个子表达式是我们要用的)。class regex_callback { int sum_; public: regex_callback() : sum_(0) {} template void operator()(const T& what) { sum_+=atoi(what[1].str().c_str()); } int sum() const { return sum_; } };

现在把这个函数对象的一个实例传递给std::for_each, 结果是对每一个迭代器it的解引用调用该函数对象,即对每一次匹配的子表达式进行调用。

int main() { boost::regex reg("(\\d+),?"); std::string s="1,1,2,3,5,8,13,21"; boost::sregex_iterator it(s.begin(),s.end(),reg); boost::sregex_iterator end; regex_callback c; int

sum=for_each(it,end,c).sum(); }

如你所见,传递给for_each的end迭代器是regex_iterator 一个缺省构造实例。it 和end 的类型均为boost::sregex_iterator, 即为regex_iterator的typedef. 这种使用regex_iterator 的方法要比我们前面试过的多次匹配的方法更清晰,在多次匹配的方法中我们不得不在一个循环中让起始迭代器不断地前进并调用regex_search 。

用regex_token_iterator 分割字符串

另一个迭代器类型,或者说得更准确些,迭代器适配器,就是boost::regex_token_iterator. 它与regex_iterator 很类似,但却是用于列举不匹配某个正则表达式的每一个字符序列,这对于分割字符串很有用。它也可以用于选择对哪一个子表达式感兴趣,当解引用

regex_token_iterator时,只有预订的那个子表达式被返回。考虑这样一个应用程序,它接受一些用斜线号分隔的数据项作为输入。两个斜线号之间的数据组成应用程序要处理的项。使用regex_token_iterator来分割这个字符串很容易。该正则表达式很简单。

boost::regex reg("/");

这个regex 匹配各项间的分割符。要用它来分割输入,只需简单地把指定的索引 1 传递给regex_token_iterator的构造函数。以下是完整的程序:

int main() { boost::regex reg("/"); std::string s="Split/Values/Separated/By/Slashes,";

std::vector vec; boost::sregex_token_iterator it(s.begin(),s.end(),reg,-1);

boost::sregex_token_iterator end; while (it!=end) vec.push_back(*it++);

assert(vec.size()==std::count(s.begin(),s.end(),'/')+1); assert(vec[0]=="Split"); }

就象regex_iterator 一样,regex_token_iterator 是一个模板类,它使用所包装的序列的迭代器类型来进行特化。这里,我们用的是sregex_token_iterator, 它是

regex_token_iterator 的typedef 。每一次解引用这个迭代器it,它返回当前的sub_match, 当这个迭代器前进时,它尝试再次匹配该正则表达式。这两个迭代

器类型,regex_iterator 和regex_token_iterator, 都非常有用;你应该明白,当你考虑反复调用regex_search时,就该用它们了。

更多的正则表达式

你已经看到了不少正则表达式的语法,但还有更多的要了解。这一节简单地示范一些你每天都会使用的正则表达式的其它功能。作为开始,我们先看一下一组完整的重复符;我们之前已经看到了*, +, 以及使用{} 进行限定重复。还有一个重复符,即是?. 你可能已经留意到它也可以用于声明非贪婪的重复,但对于它本身而言,它是表示一个表达式必须出现零次或一次。还有一点值得提及的是,限定重复符可以很灵活;下面是三种不同的用法:boost::regex reg1("\\d{5}"); boost::regex reg2("\\d{2,4}"); boost::regex reg3("\\d{2,}");

第一个正则表达式匹配5个数字。第二个匹配2个, 3个, 或者4个数字。第三个匹配2个或更多个数字,没有上限。

另一种重要的正则表达式特性是使用元字符^ 表示非字符类别。用它来表示一个匹配任意不在给定字符类别中的字符;即你所列字符类别的补集。例如,看如下正则表达式。boost::regex reg("[^13579]");

它包含一个非字符类别,匹配任意不是奇数数字的字符。看一下以下这个小程序,试着给出程序的输出。

int main() { boost::regex reg4("[^13579]"); std::string s="0123456789"; boost::sregex_iterator

it(s.begin(),s.end(),reg4); boost::sregex_iterator end; while (it!=end) std::cout << *it++; }

你给出答案了吗?输出是"02468",即所有偶数数字。注意,这个字符类别不仅匹配偶数数字,如果输入字符串是"AlfaBetaGamma",那么也会全部匹配。

我们看到的这个元字符, ^, 还有另一个意思。它可以用来表示一行的开始。而元字符$ 则表示一行的结束。

错的正则表达式

一个错的正则表达式就是一个不遵守规则的正则表达式。例如,你可能忘了一个右括号,这样正则表达式引擎将无法成功编译这个正则表达式。这时,将抛出一个bad_expression 类

型的异常。正如我前面提到的,这个异常的名字将会在下一版本的Boost.Regex中被修改,还有在即将加入Library Technical Report的版本中也是。异常类型bad_expression 将被更名为regex_error.

如果你的应用程序中的正则表达式全都是硬编码的,你可能不用处理错误表达式,但如果你是接受了用户的输入来作为正则表达式,你就必须准备进行错误处理。这里有一个程序,提示用户输入一个正则表达式,接着输入一个用来对正则表达式进行匹配的字符串。由用户进行输入时,总是有可能会导致无效的输入。

int main() { std::cout << "Enter a regular expression:\n"; std::string s; std::getline(std::cin, s); try { boost::regex reg(s); std::cout << "Enter a string to be matched:\n"; std::getline(std::cin,s); if (boost::regex_match(s,reg)) std::cout << "That's right!\n"; else std::cout << "No, sorry, that doesn't match.\n"; } catch(const boost::bad_expression& e) { std::cout << "That's not a valid regular expression! (Error: " << e.what() << ") Exiting...\n"; } }

为了保护应用程序和用户,一个try/catch 块用于处理构造时抛出boost::regex 的情形,这时会打印一个提示信息,而程序会温和地退出。用这个程序来测试,我们开始时输入一些合理的数据。

Enter a regular expression: \d{5} Enter a string to be matched: 12345 That's right!

现在,给一些错误的数据,试着输入一个错误的正则表达式。

Enter a regular expression: (\w*)) That's not a valid regular expression! (Error: Unmatched ( or \() Exiting...

在regex reg构造时,就会抛出一个异常,因为这个正则表达式不能被编译。因此,进入到catch 的处理例程中,程序将打印一个错误信息并退出。你只需知道有三个可能会发生异常的地方。一个是在构造一个正则表达式时,就象你刚刚看到的那样;另一个是使用成员函数assign 把正则表达式赋给一个regex 时。最后一个是,regex迭代器和算法也可能抛出异常,如果内存不够或者匹配的复杂度过快增长的话。

Regex 总结

无可争议,正则表达式是非常有用和重要的,而本库给C++带来了强大的正则表达式功能。传统上,用户除了使用POSIX C API来实现正则表达式功能以外,别无选择。对于文本处理的验证工作,正则表达式比手工编写分析代码要灵活和可靠得多。对于查找和替换,使用正则表达式可以优美地解决很多相关问题,而不用它们则根本无法解决。

Boost.Regex是一个强大的库,因此不可能在这一章中完全覆盖它所有的内容。同样,正则表达式的完美表现和广泛的应用范围意味着本章也不仅仅是简单地介绍一下它们。这个主题可以写成一本单独的书。要知道更多,可以学习Boost.Regex的在线文档,并且找一本关于正则表达式的书(考虑一下参考书目中的建议)。不论Boost.Regex有多强大,正则表达式有多广多深,初学者还是可以有效地使用本库中的正则表达式。对于那些由于C++不支持正则表达式而选择了其它语言的程序员,欢迎你们回家。

Boost.Regex并不是C++程序员唯一可以使用的正则表达式库,但它的确是最好的一个。它易于使用,并且在匹配你的正则表达式时快如闪电。你应该尽可能去用它。

Boost.Regex 的作者是Dr. John Maddock.

boost库的介绍

Boost是什么?一套开放源代码、高度可移植的C++库。 谁发起的?C++标准委员会库工作组。所以,质量保证,不怕遇到假冒伪劣产品。 Boost内容广泛,数值计算、泛型编程、元编程、平台API……不妨从容选择自己感兴趣的部分,细细品味。 有些什么呢?瞧瞧: 字符串及文本处理 Boost.Regex 正则表达式是解决大量模式匹配问题的基础。它们常用于处理大的字符串,子串模糊查找,按某种格式tokenize字符串,或者是基于某种规则修改字符串。由于C++没有提供正则表达式支持,使得有些用户被迫转向其它支持正则表达式的语言,如Perl, awk, 和 sed。Regex提供了高效和强大的正则表达式支持,基于与STL同样的前提而设计,这使得它很容易使用。Regex已被即将发布的Library Technical Report接受。更多的信息,请见"Library 5: Regex.". Boost.Spirit Spirit库是一个多用途的、递归的语法分析器生成框架。有了它,你可以创建命令行分析器,甚至是语言预处理器[1]。它允许程序员直接在C++代码里使用(近似于)EBNF的语法来指定语法规则。分析器非常难写,对于一个特定的问题,它们很快就变得难于维护和看懂。而Spirit解决了这些问题,而且达到了与手工制作的分析器一样或几乎一样的性能。 Boost.String_algo 这是一组与字符串相关的算法。包括很多有用的算法,用于大小写转换,空格清除,字符串分割,查找及替换,等等。这组算法是目前C++标准库里已有功能的扩展。 Boost.Tokenizer 这个库提供了把字符序列分割成记号(token)的方法。通用的语法分析任务包括了在已分割的文本流里查找数据。如果可以把字符序列视为多个元素的容器将很有帮助,容器中的元素被执照用户定义的规则所分割。语法分析就成为了在这些元素上进行操作的单个任务,Tokenizer正好提供了这种功能。用户可以决定字符序列如何被分割,在用户请求新的元素时,库将找出相应的记号。 数据结构, 容器, 迭代器, 和算法 Boost.Any Any库支持类型安全地存储和获取任意类型的值。当你需要一个可变的类型时,有三种可能的解决方案:

初学者 你应当如何学习C 以及编程

初学者,你应当如何学习C 以及编程 软件小兵 ruanjianxiaobing@sohu 作者:未知文章来源:天极Yesky软件频道 Javascript是世界上最受误解的语言,其实C 何尝不是。坊间流传的错误的C 学习方法一抓就是一大把。我自己在学习C 的过程中也走了许多弯路,浪费了不少时间。 为什么会存在这么多错误认识?原因主要有三个,一是C 语言的细节太多。二是一些著名的C 书籍总在(不管有意还是无意)暗示语言细节的重要性和有趣。三是现代C 库的开发哲学必须用到一些犄角旮旯的语言细节(但注意,是库设计,不是日常编程)。这些共同塑造了C 社群的整体心态和哲学。 单是第一条还未必能够成气候,其它语言的细节也不少(尽管比起C 起来还是小巫见大巫),就拿Javascript来说,作用域规则,名字查找,closure, for/in,这些都是细节,而且其中还有违反直觉的。但许多动态语言的程序员的理念我猜大约是学到哪用到哪罢。但C 就不一样了,学C 之人有一种类似于被暗示的潜在心态,就是一定要先把语言核心基本上吃透了才能下手写出漂亮的程序。这首先就错了。这个意识形成的原因在第二点,C 书籍。市面上的C 书籍不计其数,但有一个共同的缺点,就是讲语言细节的书太多——《C gotchas》,《Effective C 》,《More Effective C 》,但无可厚非的是,C 是这样一门语言:要拿它满足现代编程理念的需求,尤其是C 库开发的需求,还必须得关注语言细节,乃至于在C 中利用语言细节已经成了一门学问。比如C 模板在设计之初根本没有想到模板元编程这回事,更没想到C 模板系统是图灵完备的,这也就导致了《Modern C Design》和《C Template Metaprogramming》的惊世骇俗。 这些技术的出现为什么惊世骇俗,打个比方,就好比是一块大家都认为已经熟悉无比,再无秘密可言的土地上,突然某天有人挖到原来地下还蕴藏着最丰富的石油。在这之前的C 虽然也有一些细节,但也还算容易掌握,那可是C 程序员们的happy old times,因为C 的一切都一览无余,everything is figured out。然而《Modern C Design》的出世告诉人们,“瞧,还有多少细节你们没有掌握啊。”于是C 程序员们久违的激情被重燃起来,奋不顾身的踏入细节的沼泽中。尤其是,模板编程将C 的细节进一步挖掘到了极致——我们干嘛关心涉及类对象的隐式转换的优先级高低?看看boost::is_base_of就可以知道有多诡异了。 但最大的问题还在于,对于这些细节的关注还真有它合适的理由:我们要开发现代模板库,要开发active library,就必须动用模板编程技术,要动用模板编程技术,就必须利用语言的犄角旮旯,enable_if,type_traits,甚至连早就古井

心跳检测(应用Boost库)

毕业设计(论文) 题目 学院名称计算机科学与技术学院 指导教师 职称 班级本07计算机01班 学号 学生姓名

目录

摘要 随着Internet快速发展,大量的P2P出现给人们的生活交流带来许多便利。然而由于人们需求的不断提高,对于P2P系统的可靠安全行性,同时也提出了新的要求。对于覆盖世界的网络中,随时都有可能出现故障。对于研究者希望 P2P系统有自动检测到故障的原因自动修复的功能。在这方面许多人都在不断的进行研究实验。 本文研究的主要方面是P2P存储系统与故障维护中的心跳检测技术。心跳检测技术是一种检测网络连接故障的技术,根据服务端和客户端各自的心跳检测软件,相互之间发送消息即心跳报文来检测故障,判断网络连接是否正常,系统是否工作。这篇论文设计了一个能管理几百个外围节点的心跳检测系统。该系统是在Linux操作系统下,采用的TCP/UDP协议,以C/S模式,应用Boost库,以C++语言进行开发的。服务端为主控节点,客户端为外围节点,通过客户端发送心跳报文的方法来实现心跳检测。 关键词:P2P;心跳检测;Boost;Linux

ABSTRACT Along with the Internet fast development, massive P2P appears for people's life exchange brings many conveniences. However, as a result of the people demand's unceasing enhancement, regarding the P2P system's reliable security line, simultaneously also set the new request. Regarding in the cover world's network, It has the possibility to present the breakdown. Regarding the researcher hoped that the P2P system has the automatic detection breakdown reason and the automatic repair function. In this aspect many people are researching. This paper mainly researches the heart beat technology of P2P memory system and failure detection. Heat beat technology is the technology that it detects network fault, as sending messages between server and client. And it can estimate whether the network and P2P system are working naturally. The paper introduces the P2P system can manage hundreds of the client nodes . The system designs in the Linux platform, using TCP/UDP protocol, Boost libraries, C++ language and on the basis of C/S model. Server acts as the master node, the client acts as the external nodes, through the heart beat messages sent by the client to achieve the heart beat detection methods.

VC6.0下配置boost库

VC6.0下配置boost库 2008-10-11 09:18 https://www.doczj.com/doc/ea9282112.html,/yysdsyl/archive/2007/09/12/1781546.aspx 最近做开发碰到了长字符串匹配、搜索的问题,最先想到的是使用正则表达式,简单、高效。 但是我用的开发工具是VC6.0,不支持正则表达式。 上网baidu一下,发现支持正则的库还真不少,大概有以下几种:boost,GNU,VC7带的ATL 中的和微软发布的greta。 网上的朋友对boost评价不错,决定就使用是它了! 1、接下来的就是下载boost库,网上很好找。我下载的是压缩包,20多M,解压后将近100多M。 我解压的目录是D:\boost 2、然后是编译,我只要支持正则表达式就可以,因此只需要编译 D:\boost\libs\regex\build目录下的文件。据说全部编译要花将近2个小时,没有验证过,在我家里的机器上编译正则表达式部分只用了不到5分钟。 网上介绍的如何编译最多的一篇文章是“VC利用boost库解析正则表达式”,如果有人能根据这篇文章编译成功不妨告诉小弟一声…… 以下是我的操作: 在“运行”里输入“cmd”,打开命令提示符; 输入命令“cd D:\boost\libs\regex\build”//设置当前目录 输入命令“D:”//转到当前目录 接下来是很关键的一步: 很多文章是这样说的“输入 nmake -fvc6.mak” 但是出现了“'nmake' 不是内部或外部命令,也不是可运行的程序或批处理文件。”的错误提示。 然后你就会拼命查找原因,结果又有文章上说是环境变量没配置好,然后给出一堆“set”。也有的文章说是运行一下visual studio安装目录下的VC98\Bin\VCVARS32.BAT文件就OK 了。 你按照文章作者的方法做的,结果发现问题依旧! 以上说法都是正确的,但是说得都不是很完整,出现错误提示的根本原因就是环境变量没配置好,不识别nmake命令,配置过jdk的朋友就很容易明白。如果按照作者的要求搞一堆“set”,未免大题小作了吧,因为我们只需要用一次'nmake' 就可以解决问题了。VCVARS32.BAT正式配置环境变量的批处理文件,但是配置的参数只在当前窗口有效,也就

了解 Boost Filesystem Library

了解 Boost Filesystem Library C++语言(实际上是C++标准)的最常见问题之一是,缺乏定义良好的库来帮助处理文件系统查询和操作。由于这个原因,程序员不得不使用本机操作系统提供的应用程序编程接口(Application Program Interfaces,API),而这使得代码不能在平台之间移植。以下面的简单情况为例:您需要确定某个文件是否是Directory 类型。在Microsoft? Windows? 平台中,可以通过调用GetAttributes库函数(在windows.h 头文件中定义)进行此操作: DWORD GetFileAttributes (LPCTSTR lpFileName); 对于目录,所得到的结果应该为FILE_ATTRIBUTE_DIRECTORY,而您的代码必须检查是否为此结果。在UNIX? 和Linux? 平台上,可以通过使用stat或fstat函数及sys/stat.h 中定义的S_ISDIR 宏来实现相同的功能。您还必须理解stat结构。下面是对应的代码: #include #include int main() { struct stat s1; int status = stat(, &s1); printf(“Path is a directory : %d\n”, S_ISDIR(s1.st_mode)); return 0; } 对于I/O 操作较多的程序,这样的不一致就意味着需要进行大量的工程工作才能在平台间移植代码。正是因为这个原因,我们才引入了Boost Filesystem Library。这个广泛使用的库提供了安全、可移植且易用的C++接口,用于执行文件系统操作。可以从Boost站点免费下载此库。 使用boost::filesystem 的第一个程序 在深入研究Boost Filesystem Library 的更多细节之前,请看一下清单1中所示的代码;此代码使用Boost API 确定某个文件的类型是否为Directory。 清单1. 用于确定某个文件的类型是否为Directory 的代码 #include #include “boost/filesystem.hpp” int main() { boost::filesystem::path path("/usr/local/include"); // random pathname bool result = boost::filesystem::is_directory(path); printf(“Path is a directory : %d\n”, result); return 0; } 此代码非常明了易懂,您并不需要了解任何系统特定的例程。此代码经过验证,能在不用修改的情况下在gcc-3.4.4 和cl-13.10.3077 上成功编译。

VS2010 C++下编译调试MongoDB源码

VS2010 C++下编译调试 MongoDB源码 考虑到m ongodb使用了boost库源码,参考m ongodb官方文档后,下载编译boost版本是1.42(时间为2010-2-2)或更新版本: boost版本1.42: https://www.doczj.com/doc/ea9282112.html,/projects/boost/files/boost/1.42.0/boost_1_42_0.zip/download 下载boost源码之后,我把boost解压在D盘。 1.在D:\boost_1_42_0\下找到该批处理文件bootstrap.bat,以vs2010命令行方式运行它,并最终生成bjam.exe可执行文件(详细结果及错误信息见生成的bjam.log日志)。 2.将生成的bjam.exe文件拷贝到“D:\boost_1_42_0”目录下,运行下面命令行: bjam stage variant=debug --stagedir="d:\boost_1_42_0" --with-files ystem --with-thread --with-date_time --with-program_options --layou t=versioned threading=multi toolset=msvc-10.0 如下 图:

注:i.如果要生成release链接库文件,需将上面的variant设置成release,形如:bjam stage variant=release ..... ii.如果要全部生成使用下面编译选项 bjam ...... --build-type=com plete 编译过程可能会用一些时间,最终会在"D:\boost_1_42_0" 生成一个lib目录,里面包括刚生成的库文件。 3.下载已用vs2010编译的SpiderMonkey库文件及源码包,并将其解压到D盘下,下载链接: https://https://www.doczj.com/doc/ea9282112.html,/dwight/vc2010_js 将该文件夹名称改为“js”(因为m ongodb项目会默认指定该路径寻找可用的lib及c源文件),

boost升压电路

一种实用的BOOST电路 0 引言 在实际应用中经常会涉及到升压电路的设计,对于较大的功率输出,如70W以上的DC /DC升压电路,由于专用升压芯片内部开关管的限制,难于做到大功率升压变换,而且芯片的价格昂贵,在实际应用时受到很大限制。考虑到Boost升压结构外接开关管选择余地很大,选择合适的控制芯片,便可设计出大功率输出的DC/DC升压电路。 UC3842是一种电流型脉宽调制电源芯片,价格低廉,广泛应用于电子信息设备的电源电路设计,常用作隔离回扫式开关电源的控制电路,根据UC3842的功能特点,结合Boos t拓扑结构,完全可设计成电流型控制的升压DC/DC电路,且外接元器件少,控制灵活,成本低,输出功率容易做到100W以上,具有其他专用芯片难以实现的功能。 1 UC3842芯片的特点 UC3842工作电压为16~30V,工作电流约15mA。芯片内有一个频率可设置的振荡器;一个能够源出和吸入大电流的图腾式输出结构,特别适用于MoSFET的驱动;一个固定温度补偿的基准电压和高增益误差放大器、电流传感器;具有锁存功能的逻辑电路和能提供逐个脉冲限流控制的PWM比较器,最大占空比可达100%。另外,具有内部保护功能,如滞后式欠压锁定、可控制的输出死区时间等。 由UC3842设计的DC/DC升压电路属于电流型控制,电路中直接用误差信号控制电感峰值电流,然后间接地控制PWM脉冲宽度。这种电流型控制电路的主要特点是: 1)输入电压的变化引起电感电流斜坡的变化,电感电流自动调整而不需要误差放大器输出变化,改善了瞬态电压调整率; 2)电流型控制检测电感电流和开关电流,并在逐个脉冲的基础上同误差放大器的输出比较,控制PWM脉宽,由于电感电流随误差信号的变化而变化,从而更容易设置控制环路,改善了线性调整率; 3)简化了限流电路,在保证电源工作可靠性的同时,电流限制使电感和开关管更有效地工作; 4)电流型控制电路中需要对电感电流的斜坡进行补偿,因为,平均电感电流大小是决定输出大小的因素,在占空比不同的情况下,峰值电感电流的变化不能与平均电感电流变化相对应,特别是占空比,50%的不稳定性,存在难以校正的峰值电流与平均电流的误差,即使占空比<50%,也可能发生高频次谐波振荡,因而需要斜坡补偿,使峰值电感电流与平均电感电流变化相一致,但是,同步不失真的斜坡补偿技术实现上有一定的难度。

boostlog

Boost Log 简介 Boost Log Overview VIM Research Group 先进感知与控制实验室 中国科学技术大学信息科学技术学院 2015年2月

修改记录 Index Author Revision Date Remark 1 江坤V1.0 2014-02-09 初始版本

1. 安装 (4) 1.1. 软硬件需求 (4) 1.1.1.软件需求 (4) 1.1.2.硬件需求 (4) 1.2. 安装流程 (4) 2. Boost log 简介 (5) 3. Boost Log 基本使用流程 (6) 3.1. 案例一:Boost Log简单输出到控制台 (6) 3.2. 案例二:Boost Log简单输出到控制台 (7) 3.3. 案例三:Boost Log简单输出到控制台 (7) 4. 结论 (9)

本文档用于描述boost log 的安装,日常使用以及功能扩展。 1.安装 本部分描述boost 1.57.0的安装方法。 1.1.软硬件需求 1.1.1.软件需求 安装boost库的主机需支持GCC和GCC-C++之外,还需要两个开发库:bzip2-devel 和python-devel。 1.1. 2.硬件需求 运行Ubuntu12.04操作系统的主机一台。 1.2.安装流程 首先于Boost Libraries的官网下载Boost 1.57.0的安装包,下载地址如下http://www.boost .org/users/history/version_1_57_0.html。然后解压缩,进入到boost_1_57_0的目录下。 若在本机之前已安装过老版本的boost库,需要将之前include文件夹下和动态库中boost 库的相关文件删除,然后再编译安装,由于boost源码包中自带配置脚本,可直接使用,即运行booststrap.sh这个脚本配置。然后按照提示信息,输入sudo ./b2指令编译,然后就是漫长的等待,等待其是否编译成功。当输出如下信息表明编译成功: 若为安装成功需按照提示信息做相应处理,若未安装bzip2-devel 或python-devel会提示报错此时需安装相应的库,再重新安装。 最后运行./b2 install --prefix=/usr/local指令完成boost库的安装,安装后的头文件在 /usr/local/include/boost里面,而相应的库在/usr/local/lib/libboost_*。

高升压比交错并联Boost电路的分析

高升压比交错并联Boost电路的分析 类别:电源技术阅读:869 摘要:文章分析了传统BooST电路在实际应用中存在的问题,提出了一种改进型的交错并联Boost电路。在电感电流连续模式下,根据占空比大于或小于0。5的情况,详细分析电路的工作过程,推导了稳态情况下输出输入电压关系式,最后通过仿真验证了理论分析的正确性。0 引言升压变换器是最常用的一种变换器,随着新能源的推广,由于太阳能、燃料电池、蓄电池等输入源具有输入电压较低的特性,升压变换器成为不可或缺的关键部件。常用的非隔离Boost升压变换器,在高输出电压场合,由于寄生参数的影响不可能达到很高的输入输出电压比。而另一种升压电路是隔离升压电路,例如正激、反激电路。隔离升压电路中必须用到的变压器通常具有隔离、变压的功能,在那些不需要隔离或体积要求较小的应用场合,通过变压器升压就很难满足要求,另外变压器漏感引起的一系列问题,比如开关电压过冲,EMI等,常常对电源本身及周围设备带来安全隐患。 为了克服常用升压变换器在大功率、高输入输出变比等场合应用的限制,本文研究分析了一种新的电路拓扑结构及其工作方式,并对其进行了仿真验证。 1 工作原理下面分析Boost电路存在的不足,在理想情况下: M(D)=U0Uin= 11-D(1)根据式(1),在一定的输入电压下,理论上可以产生任意高于输入电压的输出电压。而实际情况中,由于电感、二极管、开关管都会产生一定的损耗,这些损耗可以等效为一个与电感串联的电阻RL,如图1所示: 图 1 Boost等效电路图此时根据磁平衡原理: 由式(2)、(3)可得:

根据式(4),在不同的RL/R 情况下,M(D)如图2所示。由此可见,在实际电路中,Boost电路升压比有限制极限,输出电压一般能达到输入电压的4~5倍。在大功率应用环境中,由于损耗严重,升压比反而更低。 为了克服上述非隔离升压电路的不足,本文研究的升压变换器如图3所示,它由交错并联Boost电路与电容串联组合而成。 图 2 升压比与占空比关系曲线图 图3 高升压比交错并联Boost电路结构图在电感电流连续模式下,当占空比大于0。5时,系统工作原理时序如图4所示,PS1、PS2分别为开关管S1、S2的驱动脉冲。ID1、ID2分别为流过续流二极管D1、D2的电流。

Windows版bjam的安装和配置

1、下载boost(或bjam)的源码,在命令行下执行如下命令: cd \tools\jam\src .\build.bat 其中指的是boost源码的根目录。这两条命令执行完毕,会产生一个bin.ntx86文件夹,里面含有一个编译生成的bjam.exe。将bjam.exe复制到C:\WINDOWS目录(或者PATH环境变量的其它取值)下。 2、在C:\Documents and Settings\All Users目录(或其它任意目录亦可)新建一个名为boost 的目录(取bjam或其它名字亦可,后面环境变量的值与此一致即可),将 \tools\build\v2目录及其前两级父目录复制到该boost目录里,则此时在C:\Documents and Settings\All Users\boost\tools\build\v2目录里可找到一个boost-build.jam文件,打开该文件并将boost-build的值改为: boost-build “C:/Documents and Settings/All Users/boost/tools/build/v2” ; 要注意此处的路径要用斜杠来隔开,但前面执行的命令涉及到的路径则用反斜杠隔开。另外,分号与前面的文字要有空格。 3、仍然在v2文件夹下,打开user-config.jam文件,找到以下一行: # using msvc ; 将“#”去掉。 4、添加BOOST_ROOT环境变量。具体操作为:右击“我的电脑”,选择“属性”->“高级”->“环境变量”,在“系统变量”方框下方点击“新建”,出现新建系统变量对话框。变量名填上BOOST_ROOT,变量值填上“C:\Documents and Settings\All Users\boost\tools\build\v2”(此路径即boost-build.jam所在的目录,注意要用英文环境下的双引号括起来)。至此,bjam 编译环境配置完成。 5、如果步骤4的环境变量不起作用,则用户的每个工程源码根目录必须存在一个步骤2修改好的boost-build.jam,bjam程序方可正常工作。但由于bjam会从工程根目录逐级搜索至工程所在磁盘分区根目录,若在每个磁盘分区根目录都复制一份boost-build.jam,则不管用户将工程源码放在什么地方,bjam程序都能正常读取boost-build.jam,然后编译工程了。 注意:在装bjam之前,必须保证系统中已安装了Visual Studio,否则无法编译出bjam.exe。如果想删除bjam,只需手动将C:\WINDOWS\bjam.exe、boost目录(用户创建的)和相关环境变量删除即可。 已发现及解决问题: 1、Visual Studio 2010的设置问题 如果系统安装的是Visual Studio 2010,则还需要向系统环境变量添加以下路径(假设VS安装在D盘): D:\Program Files\Microsoft Visual Studio 10.0\VC\bin 否则在编译bjam或者利用bjam编译用户工程时会报错,前者会提示找不到cl等命令,后者则会提示多个jam文件运行出错。

Boost编译和安装说明

Boost编译和安装说明 一、下载和安装 从官方主页https://www.doczj.com/doc/ea9282112.html,下载最新版,因为boost一部分类是需要编译成库才能使用的,所以需要准备好boost专用的编译辅助工具bjam。可直接使用boost安装包中附带的bjam源码来编译出bjam。 将boost安装包解压到E:\boost_1_53_0,运行E:\boost_1_53_0\bootstrap.bat批处理,会复制E:\boost_1_53_0\tools\build\v2\engine\ bin.ntx86\bjam.exe到目录E:\boost_1_53_0\下,注意最后bjam.exe必须与boost-build.jam在同级目录。 二、编译 打开命令提示符(cmd.exe)窗口并执行bjam,使用--help查看命令帮助。bjam的命令行参数涉及具体库的选择,会影响编译后的硬盘空间。 使用bjam命令如:bjam stage --toolset=msvc-10.0 --without-python --without-wave --without-test --stagedir="E:\boost_1_53_0_vc10" link=shared runtime-link=shared threading=multi debug release 下面详细解释一下每个参数的含义: 1)stage/install:stage表示只生成库(dll和lib),install还会生成包含头文件的 include目录。推荐使用stage,因为install生成的这个include目录实际就是boost 安装包解压缩后的boost目录(E:\boost_1_53_0\boost,只比include目录多几个非hpp的小文件),可以直接使用,而且不同的IDE都可以使用同一套头文件。 2)toolset:指定编译器,可选的如borland、gcc、msvc(VC6)、msvc-9.0(VS2008)、 msvc-10.0(VS2010)等。 3)without/with:选择不编译/编译哪些库,默认是全部编译。例如,without-python意 思是不需要编译python库。如果选择编译python的话,应该到python官方主页 https://www.doczj.com/doc/ea9282112.html,下载安装。 4)stagedir/prefix:stage时使用stagedir,install时使用prefix,表示编译生成文 件的路径。如果使用了install参数,那么还将生成头文件目录。推荐给不同的IDE 指定不同目录 5)build-dir:编译生成的中间文件的路径。默认就在根目录(E:\boost_1_53_0)下,目 录名为bin.v2,等编译完成后可具体查看一下是否生成了lib、dll文件。如果不需要可直接删除bin.v2目录 6)link:生成动态链接库/静态链接库。动态链接库使用shared方式,静态链接库使用 static方式。注意,static方式下生成的很多静态链接库大小都在几兆、几十兆。不推荐以static方式编译(without掉),巨型库黑名单:wave、graph、math、regex、test、program_options、serialization、signals。 7)runtime-link:动态/静态链接C/C++运行时库,有shared和static两种方式,与link 参数组合有4种方式。但通常一个工程用动态链接那么所有库都用动态链接,如果用静态链接那么所有库都用静态链接。所以只需要编译2种组合即可,即link=shared runtime-link=shared和link=static runtime-link=static。 8)threading:单/多线程编译。一般使用多线程程序,要指定multi方式;如果需要单线 程环境,使用single方式。

Apache Mesos底层基础库

Apache Mesos底层基础库 Protocal Buffer是google开源的用于数据交换的库,常用于跨语言的数据访问,担任的角色一般为对象的序列化反序列化。另一个与之类似的开源软件是facebook开源的thrift,它们两个最大区别是thrift提供了自动生成RPC的功能而Protocal Buffer需要自己实现,但Protocal Buffer 的一个优势是其序列化反序列化非常高效。 AD: 1.Protocol buffer Protocal Buffer是google开源的用于数据交换的库,常用于跨语言的数据访问,担任的角色一般为对象的序列化反序列化。另一个与之类似的开源软件是facebook开源的thrift,它们两个最大区别是thrift提供了自动生成RPC的功能而Protocal Buffer需要自己实现,但Protocal Buffer 的一个优势是其序列化反序列化非常高效。 2.Libprocess libprocess是采用CC++编写的高效消息传递编程模型(基于消息传递的网络通信模型,而不是RPC),由伯克利开源。其整个实现非常简单,包括最基本的消息发送和接收等。 2.1Libprocess模型 在mesos中,主要有四个角色,分别是:mesos-master,mesos-slave,framework(HadoopSpark MPI等)scheduler,executor(在mesos-slave上执行framework task的组件),每种角色均是一个Process,在实现时会继承libprocess中的ProtobufProcess类(它又继承了Process类),这样,它们均会编成一个后台运行且不断监听protocal buffer消息的socket server,如下图所示: 2.2各种常用函数 Libprocess+protocol buffer组合是mesos最底层最重要的消息传递基础库(没有采用RPC机制),由于该库采用了基于Protocal Buffer消息传递的通信机制),因而非常高效。Mesos常用的两个头文件是libprocess\include\process下的process.hpp和protobuf.hpp,这两个提供了用于消息传递的API,其中process.hpp是最核心的文件水草玛瑙 https://www.doczj.com/doc/ea9282112.html,,提供了原始的接口,而protobuf.hpp是在process.hpp基础上,加入了ProtocalBuffer对象参数,使ProtocalBuffer使用起来更加容易。 (1) install void install(void (T::*method)(P1C),P1 (M::*param1)() const); 安装一个处理ProtocalBuffer消息的handler,其中,消息类型是M,该消息对应的处理函数是method,函数参数为M::*param1。举例:mesos中slaveslave.cpp: install( Slave::newMasterDetected, NewMasterDetectedMessage::pid); 安装一个处理NewMasterDetectedMessage(ProtocalBuffer对象)的handler,mesos slave一旦接收到该消息,便会调用newMasterDetected函数处理,且该函数的输入参数是NewMasterDetectedMessage消息中的pid属性。 voidinstall(conststd::string name,void(T::*method)(constUPID ,conststd::string )) 安装一个处理字符串的handler,也就是说,当收到字符串name后,调用函数method进行处理。这个API在mesos中的典型应用时高山茶 https://www.doczj.com/doc/ea9282112.html,维持master与slave之间的心跳,以确定彼此活着: 在slaveslave.cpp中: install( PING , Slave::ping);voidSlave::ping(constUPID from,conststring body){send(from, PONG } 在mastermaster.cpp中: install( PONG , SlaveObserver::pong);voidpong(constUPID from,conststring body){timeouts=0;pinged=false;}voidtimeout(){if(pinged){Sowehaven'tgotbackapongyet...if(++timeo uts =MAX_SLA VE_TIMEOUTS){deactivate();return;}}send(slave, PING );pinged=true;delay(SLA VE_PONG_TIMEOUT,self(), SlaveObserver::timeout);} (2) send voidsend(constprocess::UPID to,constgoogle::protobuf::Message message) 向某个UPID上发送消息,其中UPID代表一个socket,里面含有ip和port信息,而消息message

boost库编译

①打开你是boost_1_37_0文件夹 ②打开tools/jam/src ③点击build.bat 稍等一下会生成一个新的文件夹,打开里面有一个bjam.exe,复制它然后将它粘 贴到boost_1_37_0文件夹里面 然后打开vc2005的命令行:开始->所有程序->visualstudio 2005->visual sudio tools->命令提示(也就是那个黑色doc的标志) (许多人用cmd 那个doc命令,许多情况下是不行的,我就试过) 假如你的boost文件夹在E:/boost_1_37_0; 那么可以这样打命令: 1 E:然后回车 2 cd boost_1_37_0 然后回车 3 bjam.exe 然后回车 你的boost库就开始编译了,时间很长~ 剩下的别人也说得较为清楚,呵呵,;-), 我玩boost很久了,从1.34开始就一直玩,很不错 4 回答者:a_xr13800 - 二级 2009-1-7 22:01 我来评论>>提问者对于答案的评价: 谢谢哦 相关内容 ? boost 1_33_1 在VC6.0上的安装出现问题 2006-12-17 ? 1.0 bar boost是什么意思 2009-2-7 ? 笔记本《上、下、左、右,》键不起作用调不成boost引导顺序,怎样装系 统啊 2010-5-12 ? 联想Y460 I3 intel turbo boost technology device驱动装不了,是什么原 因 3 2010-8-1 ? 我的主板是技嘉770t-us3 装了easy tune 6 可是找不到easy boost 2010-4-28 等待您来回答更多 ?2回答为什么不用卫星来测控嫦娥二号? ?2回答xyhhdh商业理财 ?0回答最近刚买的房子,走的是商业贷款,现交完订金,马上就去交首付款,我... ?0回答用VS2008 新建一个MFC单文档工程,菜单里的改变应用程序外观是怎么实现... ?1回答visual studio 2008 SP1里有STL吗?? ?2回答各位编程爱好者,请帮我看看这道C语言题,将中缀表达式转化为后缀表达... ?2回答请问高手,汉武大帝第七集里贵妃们玩的什么游戏???

boost库命名规则的优点

boost库命名规则的优点 作者:朱金灿 来源:https://www.doczj.com/doc/ea9282112.html,/clever101 我们编译出来的二进制库文件该如何命名呢?当我经验尚浅时,发现这个不 是问题——就以工程名来命名呗。但慢慢发现这种命名是有很多问题的(特别是当你升级编译器时,比如从VS 2005升级到VS2010时,或者是软件打包时):比如debug版本和release版本的库区分不开,不同版本的编译器编出的库区分不开(很多时候面对一个库你不知道它是VC6.0、VS 2005还是VS 2008编出来的),静态 库还是导入库区分不开,代码库的版本不知道……可能你会说:不是有个depends 工具,用它打开查看一下就知道了。问题一是假如库文件很多时,谁愿意一一去查看;二是静态库还是导入库靠depends工具是判断不出来的。而在开发时混用不同版本的库文件,会造成很多莫名其妙的问题。 如何解决这个问题?唯有靠规范的命名。怎样才算是规范的库文件命名?我觉得指导原则应该是见名知意。如果根据见名知意这个原则来衡量,我发现boost库 是做得比较规范的。关于boost库的命名规则,具体请见这篇文章:Boost 库命名 规则(翻译)。boost库的命名,涵括了下面几方面信息: 1.库的功能信息(即是序列化库、正则库还是其它功能的库) 2.静态库还是导入库(静态库以lib开头) 3.构建该库的具体编译器信息 4.线程标签(是多线程还是单线程) 5.影响库与其它编译代码的互操作性的细节的编码(debug版本还是release版 本,是否使用了STLPORT) 6.boost库的版本信息 面对这样规范的命名,你还会混用吗?据此我也简单制定了一个Windows环境下的库文件的命名规则: 静态库命名:lib+工程名_编译器信息_版本信息_互操作性细节信息.lib, 这里的互操作性细节信息初步分为debug版本、release版本以及多字节版本和unicode版本。 一个简单例子就是libpng_vc80_1_3_d.lib,表示这个是由VS 2005编译出来的png静态库,是debug版本(.lib前面用一个d来区分),库版本为V 1.3,采用多字节字符集编译。(对应的release版本命名为libpng_vc80_1_3.lib)。如果是unicode版本,名称则是libpng_vc80_1_3_ud.lib和libpng_vc80_1_3_u.lib (多了一个字母u)。

boost电路设计介绍

BOOST电路设计介绍 0 引言 在实际应用中经常会涉及到升压电路的设计,对于较大的功率输出,如70W以上的DC/DC升压电路,由于专用升压芯片内部开关管的限制,难于做到大功率升压变换,而且芯片的价格昂贵,在实际应用时受到很大限制。考虑到Boost升压结构外接开关管选择余地很大,选择合适的控制芯片,便可设计出大功率输出的DC/DC 升压电路。 UC3S42是一种电流型脉宽调制电源芯片,价格低廉,广泛应用于电子信息设备的电源电路设计,常用作隔离回扫式开关电源的控制电路,根据UC3842的功能特点,结合Boost拓扑结构,完全可设计成电流型控制的升压DC/DC电路,且外接元器件少,控制灵活,成本低,输出功率容易做到100W以上,具有其他专用芯片难以实现的功能。 1 UC3842芯片的特点 UC3842工作电压为16~30V,工作电流约15mA。芯片内有一个频率可设置的振荡器;一个能够源出和吸入大电流的图腾式输出结构,特别适用于MoSFET的驱动;一个固定温度补偿的基准电压和高增益误差放大器、电流传感器;具有锁存功能的逻辑电路和能提供逐个脉冲限流控制的PWM比较器,最大占空比可达100%。另外,具有内部保护功能,如滞后式欠压锁定、可控制的输出死区时间等。 由UC3842设计的DC/DC升压电路属于电流型控制,电路中直接用误差信号控制电感峰值电流,然后间接地控制PWM脉冲宽度。这种电流型控制电路的主要特点是: 1)输入电压的变化引起电感电流斜坡的变化,电感电流自动调整而不需要误差放大器输出变化,改善了瞬态电压调整率; 2)电流型控制检测电感电流和开关电流,并在逐个脉冲的基础上同误差放大器的输出比较,控制PWM脉宽,由于电感电流随误差信号的变化而变化,从而更容易设置控制环路,改善了线性调整率; 3)简化了限流电路,在保证电源工作可靠性的同时,电流限制使电感和开关管更有效地工作; 4)电流型控制电路中需要对电感电流的斜坡进行补偿,因为,平均电感电流大小是决定输出大小的因素,在占空比不同的情况下,峰值电感电流的变化不能与平均电感电流变化相对应,特别是占空比,50%的不稳定性,存在难以校正的峰值电流与平均电流的误差,即使占空比<50%,也可能发生高频次谐波振荡,因而需要斜坡补偿,使峰值电感电流与平均电感电流变化相一致,但是,同步不失真的斜坡补偿技术实现上有一定的难度。 2 Boost电路结构及特性分析 2.1 由UC3842作为控制的Boost电路结构 由UC3842控制的Boost拓扑结构及电路分别如图1和图2所示。

相关主题
文本预览
相关文档 最新文档