b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

Boost学习指南之:正则表达式(2)

电脑杂谈  发布时间:2019-05-14 14:20:03  来源:网络整理

boost 正则_boost 中文正则支持_正则表达式 中文匹配

第二个字符串是不正确的,因为单词 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 Iterator,class Allocator=std::allocator<sub_match<Iterator> >class match_results;typedef match_results<const char*> cmatch;typedef match_results<const wchar_t> wcmatch;typedef match_results<std::string::const_iterator> smatch;typedef match_results<std::wstring::const_iterator> wsmatch;复制代码我们将使用 std::string, 所以要留意 typedef smatch, 它是 match_results<std::string::const_iterator>的缩写。

一个通用表达式是由一些元素组成的.这些元素是通用表达式中最小的匹配单位.一个元素可以是一个字符,例如a,与字符a相匹配,或者是一个特殊字符,例如$,匹配一行的结束.还可以是其他的字符,例如\来匹配一个单词的结束.也就是说要将我们想要查找的字符串放在这两个中间.这样我们就可以精确的来查找我们想要查找的字符串,而不会有其他的一些匹配情况.而如果我们用简单字符串形式来查找,我们就会得到许多的匹配情况,甚至在一个单词中的组成部分也可以成为匹配情况.例如在文件中有californian,unfortunately.如果用命令/for来查找,那么就会找到这两个单词.而如果我们用通用表达式\来进行查找,则只会精确的查找到for,而不会用其他的匹配情况.这时的命令形式如下:。这些字符都是在正则表达式中被“征用”了,称之为特殊字符,引用的时候,必须前面加 "\" 进行区分,比如你要用到 "$" 字符的时候,必须使用 "\$",这样程序才不会以为你是在匹配行尾。我们已经看到了,一个正则表达式中的许多元素才能够匹配字符串的一个字符.例如: \s 匹配的只是一个空白符.还有一些正则表达式的元素匹配的是字符之间宽度为。

通过传递一个类型 smatch 的对象给 regex_search, 我们可以得知算法如何执行成功的细节。我们的表达式中有两个子表达式,因此我们可以通过match_results的索引1得到子表达式 new . 这样我们得到一个 sub_match实例,它有一个Boolean成员,matched, 告诉我们这个子表达式是否参与了匹配。因此,对于上例的输入,运行结果将输出"The expression (new) matched!\n". 现在,你还有一些工作要做。你需要继续把正则表达式应用于输入的剩余部分,为此,你要使用另起始点的迭代器更新为上一次匹配的结束点。最后,增加两个变量来记录 new 和 delete的次数。以下是完整的程序:#include <iostream>#include <string>#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";elsestd::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", 表示替换文本为第一个和第三个子表达式。通过引用匹配的子表达式,我们可以保留匹配文本中的所有大小写,而如果我们用字符串来作替换文本则不能做到这一点。以下是解决这个问题的完整程序。

boost 正则_正则表达式 中文匹配_boost 中文正则支持

正则替换:根据正则表达式匹配内容并替换。javascript的regexp类表示正则表达式和字符串和正则表达式定义,使用正则表达式来进行强大的模式匹配和搜索和替换文本功能的方法。"搜索"->"替换",在“查找”栏中输入“%[ ^t]++^p”,“替换为”栏里不输入内容,选中正则表达式,执行替换操作即可删除文本中的空行。

只有所有输入被 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;相反,它可以清晰地表明我们刚才说到的语义,即必须匹配所有输入。关于重复和贪婪另一个容易混淆的地方是关于重复的贪婪。

当offset=2时,正则表达式为:(^.{2}) .表示除\n之外的任意字符,后面加{2} 就是匹配以数字或字母组成的前两个连续字符,加()就会将匹配到的结果提取出来,然后通过replace将匹配到的结果替换为新的字符串,形如:结果=结果+str。我们已经看到了,一个正则表达式中的许多元素才能够匹配字符串的一个字符.例如: \s 匹配的只是一个空白符.还有一些正则表达式的元素匹配的是字符之间宽度为。正则表达式如果期望着一个字符一个字符的匹配,是非常不现实的.而"匹配"这个问题,非常容易转换成"匹配了一部分",整个匹配不匹配,要看"剩下的匹配"情况.这就很好的把一个大的问题转换成了规模较小的问题:递归。

你期望这个程序的运行结果是什么?通常,一个刚开始使用正则表达式的用户会首先想到 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处停止,因为这就是表达式要成功匹配所需要的。


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-98601-2.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...