用于 VS 2008 无功能包的简单 C++ 正则表达式库 [关闭]
Posted
技术标签:
【中文标题】用于 VS 2008 无功能包的简单 C++ 正则表达式库 [关闭]【英文标题】:Simple C++ regular expressions library for VS 2008 w/o Feature Pack [closed] 【发布时间】:2013-11-18 21:55:22 【问题描述】:我正在开发一个 MFC/C++ 项目,该项目是在没有功能包的 VS 2008 中开发的。 (我不使用功能包的原因是因为这个项目需要向后兼容 Win2K,该包已过时。)
所以我想做一些简单的正则表达式匹配。
我进行了一些搜索,但我能找到的大部分内容要么无法包含在商业项目中(我的项目是),要么库本身对我的需要来说太重了(例如 Boost.Regex。)
有什么建议吗?
【问题讨论】:
【参考方案1】:如果我是你,我会使用 Boost 1.54,但不使用它们的库,只使用它们的源代码。
安装完整的 boost 发行版。在您的项目中,通过选择所有添加 C++ 文件..\boost_1_54_0\libs\regex\src\*.*
中的文件,当然还要添加标题路径。
正则表达式 src 只是代码的一大优势,它很好地符合您的项目设置,因此您的项目不依赖于他们的库。
这在您的代码大小中所占的空间非常小。但是,您也可以只复制大部分项目设置以创建一个单独的正则表达式源的 lib/dll,然后将其包含在您的其他项目中。
使用 boost,只要不随商业代码一起分发,就没有许可问题(即使那样,您只需提供归属)。
我得告诉你,boost regex 是一个很棒的引擎。
编辑2:
如果将正则表达式源添加到项目中,What libs do I need to include?
的答案是 NONE。没有库,因为所有代码都成为可执行文件的一部分。
您所要做的就是告诉您的项目安装发行版的目录(见下文)。您添加的源文件将包含它需要的 HPP 文件。只需编译。
从我的代码来看,占用空间似乎是 2-300K,这还不错。 boost regex 几乎是所有模板类 hpp 文件,它非常适合 C++。 您可以从我的示例中看到,我非常广泛地使用迭代器,这是要走的路。
我使用了很多正则表达式。我将它们保存在myconst.h/cpp
模型中,并在需要的地方包括在内。我还使用一个名为 RegexFormat (website) 的程序来管理它们。格式化/压缩/扩展/调试并从/到 C++ 字符串来回转换。让它变得容易.. 刚刚检查,他们将价格降低到 29 美元。 (我在 49 岁时得到它,哦,好吧)。
还有更多使用 boost 正则表达式的方法。 这是一个小的使用示例。我试图在不牺牲意义的情况下削减它。 它看起来仍然很大(抱歉)。
如果您还有其他问题,请随时问...
Project Properties
-------------------
Configuration Properties ->
C/C++ ->
General ->
Additional Include Directories ->
F:\Dev\boost_1_54_0 ( <-where you install the distribution )
//////////////////////////////////////////////
// ======== myconst.h ==========
#pragma once
#ifndef _myconst
#define _myconst
//
#include <boost/regex.hpp>
#include <string>
#include <iostream>
// ------------------------
using namespace std;
using namespace stdext;
using namespace boost;
// ---------------------------------------------
typedef std::string::const_iterator SITR;
#define MOD regex_constants::perl | boost::regex::no_mod_s | boost::regex::no_mod_m
#define MODx regex_constants::perl | boost::regex::no_mod_s | boost::regex::no_mod_m | regex_constants::mod_x
#define MODs regex_constants::perl | boost::regex::no_mod_m | regex_constants::mod_s
#define MODxs regex_constants::perl | boost::regex::no_mod_m | regex_constants::mod_s | regex_constants::mod_x
#define MODm regex_constants::perl | boost::regex::no_mod_s
#define MODxm regex_constants::perl | boost::regex::no_mod_s| regex_constants::mod_x
#define MODsm regex_constants::perl | regex_constants::mod_s
#define MODxsm regex_constants::perl | regex_constants::mod_s | regex_constants::mod_x
// Common regexes
extern boost::regex TextLine;
extern boost::regex TRI_TextLineReplace;
extern boost::regex TextLineReplace;
extern boost::regex BlankLinesReplace;
extern boost::regex StripBoundryWsp;
#endif _myconst // End _myconst
//
//////////////////////////////////////////////
//////////////////////////////////////////////
// ======== myconst.cpp ==========
#include "stdafx.h"
#include "myconst.h"
boost::regex TextLine (
" (?| ( [^\\r\\n]* ) \\r\\n | ( [^\\r\\n]+ ) \\z ) "
, MODx);
boost::regex TRI_TextLineReplace ( // with support to escape trigraph '??x' sequence
" ( [\\\\\"] | \\?(?=\\?) | (?<=\\?)\\? ) "
, MODx);
boost::regex TextLineReplace ( // no support to escape trigraph '??x' sequence
" ( [\\\\\"] ) "
, MODx);
boost::regex StripBoundryWsp ("\\A \\s*(?=\\S) (.+?) (?<=\\S)\\s* \\z", MODxs);
boost::regex BlankLinesReplace (
" (?: "
" (?> \\A [^\\S\\r\\n]* (?: \\z | (?=\\r\\n) ) ) "
" | (?> (?<=\\r\\n) [^\\S\\r\\n]* (?: \\z | (?=\\r\\n) ) ) "
" ) "
, MODx);
//
//////////////////////////////////////////////
//////////////////////////////////////////////
// ======== myeditor.cpp ==========
#include "stdafx.h"
#include "myconst.h"
#include "myeditor.h"
#include "makecstrdlg.h"
LRESULT MyEditor::OnMsgMakeCstring(WPARAM /*wp*/, LPARAM /*lp*/)
CMakeCstrDlg dlg;
if (dlg.DoModal() == IDOK)
if ( dlg.m_bType2 )
CString mfcstr;
GetWindowText( mfcstr );
string strSrc = mfcstr;
GetMakeCstrType2( strSrc, dlg.bTrigraph );
SetWindowText( strSrc.c_str() );
SetFocus();
return 0;
void MyEditor::GetMakeCstrType2( string& strSrc, bool bTrigraph )
if ( strSrc.length() == 0 )
strSrc.assign("\"\""); // '""'
return;
boost::regex Replacer;
if ( bTrigraph )
Replacer = TRI_TextLineReplace;
else
Replacer = TextLineReplace;
string strNewSrc = "";
string tmp;
SITR _Mstart;
SITR _Mend;
boost::smatch _M;
_Mstart = strSrc.begin();
_Mend = strSrc.end();
while ( boost::regex_search ( _Mstart, _Mend, _M, TextLine ) )
tmp.assign( _M[1].first, _M[1].second );
tmp = boost::regex_replace ( tmp, Replacer, "\\\\$1" );
strNewSrc.append( "\"" + tmp );
strNewSrc.append( "\\n\"\r\n" );
_Mstart = _M[0].second;
strSrc = strNewSrc;
//
//////////////////////////////////////////////
编辑:如果你使用 boost 正则表达式,下面会帮助你
预处理器:这些 boost 定义会很好地工作
Boost Defines (in Project Settings)
=================================
BOOST_ALL_NO_LIB
BOOST_REGEX_NON_RECURSIVE
BOOST_REGEX_BLOCKSIZE=32768
BOOST_REGEX_MAX_BLOCKS=8192
BOOST_REGEX_MAX_CACHE_BLOCKS=4096
这修复了由于 MS 无法控制自己的头文件而导致的恼人警告
=================================================
#include <intsafe.h>
#include <stdint.h>
CAUSES THIS ->
1>f:\program files\microsoft visual studio 10.0\vc\include\stdint.h(72): warning C4005: 'INT8_MIN' : macro redefinition
1> c:\program files\microsoft sdks\windows\v7.0a\include\intsafe.h(144) : see previous definition of 'INT8_MIN'
1>f:\program files\microsoft visual studio 10.0\vc\include\stdint.h(73): warning C4005: 'INT16_MIN' : macro redefinition
1> c:\program files\microsoft sdks\windows\v7.0a\include\intsafe.h(146) : see previous definition of 'INT16_MIN'
1>f:\program files\microsoft visual studio 10.0\vc\include\stdint.h(74): warning C4005: 'INT32_MIN' : macro redefinition
1> c:\program files\microsoft sdks\windows\v7.0a\include\intsafe.h(148) : see previous definition of 'INT32_MIN'
1>f:\program files\microsoft visual studio 10.0\vc\include\stdint.h(76): warning C4005: 'INT8_MAX' : macro redefinition
1> c:\program files\microsoft sdks\windows\v7.0a\include\intsafe.h(167) : see previous definition of 'INT8_MAX'
1>f:\program files\microsoft visual studio 10.0\vc\include\stdint.h(77): warning C4005: 'INT16_MAX' : macro redefinition
1> c:\program files\microsoft sdks\windows\v7.0a\include\intsafe.h(171) : see previous definition of 'INT16_MAX'
1>f:\program files\microsoft visual studio 10.0\vc\include\stdint.h(78): warning C4005: 'INT32_MAX' : macro redefinition
1> c:\program files\microsoft sdks\windows\v7.0a\include\intsafe.h(176) : see previous definition of 'INT32_MAX'
1>f:\program files\microsoft visual studio 10.0\vc\include\stdint.h(79): warning C4005: 'UINT8_MAX' : macro redefinition
1> c:\program files\microsoft sdks\windows\v7.0a\include\intsafe.h(168) : see previous definition of 'UINT8_MAX'
1>f:\program files\microsoft visual studio 10.0\vc\include\stdint.h(80): warning C4005: 'UINT16_MAX' : macro redefinition
1> c:\program files\microsoft sdks\windows\v7.0a\include\intsafe.h(173) : see previous definition of 'UINT16_MAX'
1>f:\program files\microsoft visual studio 10.0\vc\include\stdint.h(81): warning C4005: 'UINT32_MAX' : macro redefinition
1> c:\program files\microsoft sdks\windows\v7.0a\include\intsafe.h(178) : see previous definition of 'UINT32_MAX'
1>f:\program files\microsoft visual studio 10.0\vc\include\stdint.h(149): warning C4005: 'INT64_MIN' : macro redefinition
1> c:\program files\microsoft sdks\windows\v7.0a\include\intsafe.h(152) : see previous definition of 'INT64_MIN'
1>f:\program files\microsoft visual studio 10.0\vc\include\stdint.h(150): warning C4005: 'INT64_MAX' : macro redefinition
1> c:\program files\microsoft sdks\windows\v7.0a\include\intsafe.h(184) : see previous definition of 'INT64_MAX'
1>f:\program files\microsoft visual studio 10.0\vc\include\stdint.h(151): warning C4005: 'UINT64_MAX' : macro redefinition
1> c:\program files\microsoft sdks\windows\v7.0a\include\intsafe.h(189) : see previous definition of 'UINT64_MAX'
Fix 1 (preferred):
====================================================
In "\microsoft visual studio 10.0\vc\include\stdint.h" undefine them before they are re-defined
#undef INT8_MIN
#undef INT16_MIN
#undef INT32_MIN
#undef INT8_MAX
#undef INT16_MAX
#undef INT32_MAX
#undef UINT8_MAX
#undef UINT16_MAX
#undef UINT32_MAX
#undef INT64_MIN
#undef INT64_MAX
#undef UINT64_MAX
Fix 2:
====================================================
In "\boost\config\compiler\visualc.hpp" undefine BOOST_HAS_STDINT_H
//#if _MSC_VER >= 1600
#undef BOOST_HAS_STDINT_H
//# define BOOST_HAS_STDINT_H
//#endif
【讨论】:
谢谢。这是一个非常好的主意。不过我从来没有使用过Boost。你能给我一个简单的例子来说明你如何在字符串匹配上使用正则表达式吗?还有你在上面命名的那个文件夹中包含了哪些库? @c00000fd - 没有库。用上面的典型示例发布了解释。 谢谢。 Boost 不仅仅是一堆 cpp/h 文件。我完成了您代码的第一部分(myconst
部分)并在构建项目时得到了1>LINK : fatal error LNK1104: cannot open file 'libboost_regex-vc90-mt-gd-1_55.lib'
。显然我需要安装它或在其中构建一些东西......
@c00000fd - 不可能。 LINK : fatal error LNK1104: cannot open file 'libboost_regex-vc90-mt-gd-1_55.lib
是一个多线程库。有 7 或 8 个库可以使用。链接器尝试打开特定库的唯一方法是它是否在您的链接器语句中。把它拿出来。您是否在项目中包含正则表达式 src
文件?您需要做的就是将包含路径添加到发行版 heirechy 文件夹(您安装发行版的文件夹)。子目录里面会有boost
,设置父文件夹的路径。
@c00000fd - 我忘了,你必须在你的定义中告诉BOOST_ALL_NO_LIB
。将定义(我在上面发布)添加到您的项目设置中。这可以防止自动感应配置尝试加载库。【参考方案2】:
Boost 是一个很好的答案,但如果您以前从未使用过 Boost,那么较小的实现可能就足够了,并且副作用可能会更小。
Atl Server(在 Codeplex 上)在atlrx.h 中也有一个正则表达式引擎 也记录在MSDN
您也可以找到示例代码here。
【讨论】:
感谢您的建议。不幸的是,我找不到与现代 RegExp 标准兼容且没有错误的 C++ 实现......必须坚持使用 Boost。【参考方案3】:Henry Spencer 编写了一个古老但广泛使用的正则表达式库,可能包含在数百种产品中。这是您可以获得它的众多地方之一:
http://www.arglist.com/regex/
【讨论】:
感谢您的建议。不幸的是,我找不到与现代 RegExp 标准兼容且没有错误的 C++ 实现......以上是关于用于 VS 2008 无功能包的简单 C++ 正则表达式库 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
Python error: Microsoft Visual C++ 9.0 is required 解决方案