正则表达式:boost::xpressive vs boost::regex

13

我想在C++中使用正则表达式,于是我上网搜索(是的,我是个C++初学者/中级水平),找到了这个Stack Overflow回答

我真的不知道在boost::regex和boost::xpressive之间该如何选择。它们各有什么优缺点呢?

我还读到说,与boost::regex相比,boost::xpressive是一个头文件库。在Linux和Windows上静态编译boost::regex难吗(我几乎总是编写跨平台应用程序)?

我也对编译时间进行比较感兴趣。我目前使用boost::xpressive实现,但我对编译时间不太满意(但我没有与boost::regex进行比较)。

当然,我也乐意听取其他正则表达式实现方案的建议。要求是免费(像啤酒一样免费)且与http://nclabs.org/license.php兼容。

5个回答

4

一个相当重要的区别是,Boost Regex可以支持链接到ICU以获得Unicode支持(字符类等)Boost Regex ICU Support

据我所知,Boost Xpressive没有内置此类支持。


2
我会尝试通过更加理论化的方式来补充其他人的答案,深入探讨编译时正则表达式(CTR)和运行时(dynamic)正则表达式(RTR)的区别(我认为这个话题是OP问题间接涉及的)。由于历史原因,RTR更为广泛流行(大多数语言核心库实现),它们适用于在运行时确定正则表达式,而CTR则不然。两者都基于有限状态机工作。
RTR由某种通用有限状态机“编译”和解释(通用意味着其解释器方案在运行时给出,“编译”在某些内部数据结构中——当您传递正则表达式字符串时,然后在运行时解释)。但是CTR在编译时“编译”,并且是特定于特定正则表达式的,因此您无法在运行时使用它们(例如文本编辑器、文件/互联网搜索引擎等应用程序)。
但是它们先验上更有效率(从理论上说),因为经过编译时定制的有限状态机将是高效的,而具有预设表格方案的解释器则不然(一些类似情况是反射字段访问与编译时访问,或针对某些固定参数进行优化的专用函数,正如这里所指出的)。另一个优点是编译时语法检查。CTR可以通过元编程和/或代码生成来实现。
至于具体的实现——有许多RTR,但CTR不那么多。对于C++,它们是上述Boost和STL C++0x11实现。您可能需要它们来优化正则表达式性能/生成代码大小/内存使用情况,这主要与嵌入式系统或高性能特定应用程序相关。关于CTR的SO问题 寻找CTR实现更加困难,如果找到一个例子,则是Re2C代码生成器项目、Java CTR实现和包含运行时编译(转换为IL代码,而不是内部数据结构)的C#实现[有一个SO问题涉及它]
P.S.抱歉,由于声望的原因,无法发布一些相关链接。

2

在使用Boost库时,由于跨平台兼容性问题,我倾向于使用仅包含头文件的库。但缺点是,当编译器报告与库的使用相关的错误时,仅有头文件的输出往往比较晦涩难懂。


通常情况下,仅包含头文件的库会包含大量模板代码,而模板错误可能非常晦涩难懂。 - Joseph Lisee
1
"仅含头文件的库也可能存在跨平台问题。" - MQR - Elliot Cameron
1
然而,仅包含头文件的库使得在新的构建系统上收集依赖项变得更加容易。 - dhardy

2
假设你正在使用一个相当新的编译器,它很可能已经包含了一个正则表达式包。尝试只需执行 #include <regex>,看看编译器是否可以找到它。
唯一需要注意的事情是,它可能在两个不同的命名空间中(或者两个命名空间都有)。正则表达式被包含在C++标准的TR1中,并且也在(最终稿的)C++11中。TR1版本位于名为tr1的命名空间中,而标准版本与库的其余部分一样位于std中。
FWIW,这基本上与Boost regex相同,而不是Boost Xpressive。

我宁愿不使用C++0x。我正在寻找一个描述boost::regex和boost::xpressive之间区别的答案。 - orlp

2
如果你需要在运行时创建正则表达式(即让用户输入正则表达式进行搜索),那么你不能使用 xpressive,因为它仅适用于编译时。另一方面,由于它是一个编译时结构,相比于regex,它应该从优化器中获得更多的好处。我经常使用 Boost.MPL、StateChart 和 Spirit,所以220KB的编译器警告和错误对我来说并不是很困扰。如果这听起来像地狱,那就使用 Boost.Regex。如果你确实使用xpressive,我强烈建议开启-Wfatal-errors,因为它会在第一行出现“error:”之后停止编译(和进一步的错误)。在编译时间方面,Boost.Regex会更快*。xpressive使用MPL将导致编译时间大大增加。
*这假设你只构建了dll/so一次。

12
这并非完全正确。Xpressive同样支持运行时正则表达式,详见此处:http://www.boost.org/doc/libs/1_46_1/doc/html/xpressive/user_s_guide.html#boost_xpressive.user_s_guide.creating_a_regex_object.dynamic_regexes - Pablo
1
@Pablo 谢谢!我从未意识到它会这样做。你知道它使用的后端是什么吗?需要预编译库吗? - KitsuneYMG
2
这是一个仅有头文件的库。请查看安装说明:http://www.boost.org/doc/libs/1_46_1/doc/html/xpressive/user_s_guide.html#boost_xpressive.user_s_guide.installing_xpressive 我在编译时间方面没有遇到问题。我更改为使用Boost.Regex的原因是支持ICU。 - Pablo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接