在c ++项目中使用pcre2

时间:2015-09-15 07:22:55

标签: c++ c++11 visual-c++ pcre

我正在寻找在我的简单c ++应用程序中使用pcre2,(我正在使用vs2015)。 (我正在研究各种正则表达式库,一般的感觉是pcre / pcre2是最灵活的)

首先,我从官方位置(http://sourceforge.net/projects/pcre/files/pcre2/10.20/)下载了pcre2,并创建了一个非常简单的示例。

#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
...
PCRE2_SPTR subject = (PCRE2_SPTR)std::string("this is it").c_str();
PCRE2_SPTR pattern = (PCRE2_SPTR)std::string("([a-z]+)|\\s").c_str();

...
int errorcode;
PCRE2_SIZE erroroffset;
pcre2_code *re = pcre2_compile(pattern, PCRE2_ZERO_TERMINATED, 
                                PCRE2_ANCHORED | PCRE2_UTF, &errorcode,  
                                &erroroffset, NULL);
...

首先是文件&#34; pcre2.h &#34;不存在,所以我将 pcre2.h.generic 重命名为 pcre2.h

但是后来我得到了未解析的外部链接错误。

我猜我需要将一个或多个文件从源包含到项目中。 但我不愿意随意添加文件而不知道它们的作用。

有人可以提供一些简单的步骤来使用pcre2成功构建项目吗?

更新
这不是一个导入库问题,pcre2.h没有附带librar(我在其发布位置看不到的那个)。

6 个答案:

答案 0 :(得分:6)

如果有人想使用visual studio构建库

  1. 从网站下载pcre2,(http://www.pcre.org/
  2. 在Visual Studio 2015中,(或许还有其他人),创建一个空项目&#34; Win32项目&#34;并称之为pcre2。
  3. 将\ pcre2 \ src \中的所有文件复制到新创建的空项目中。
  4. 添加&#34; NON-AUTOTOOLS-BUILD&#34;中列出的所有文件(位于基础文件夹中)
    • pcre2_auto_possess.c
    • pcre2_chartables.c
    • pcre2_compile.c
    • pcre2_config.c
    • 等...
  5. 将文件 config.h.generic 重命名为 config.h
  6. 将config.h文件添加到项目中。
  7. 在您的项目中,选择所有* .c文件Go Properties&gt; C / C ++&gt;预编译标题&gt; &#34;不使用预编译的标题&#34;
  8. 选择项目,转到“属性”&gt;预处理器&gt;预处理器定义并选择下拉列表,然后添加...
    • PCRE2_CODE_UNIT_WIDTH = 8
    • HAVE_CONFIG_H
  9. 编译并创建lib文件。

答案 1 :(得分:6)

如果你不介意使用包装器,这是我的:JPCRE2

您需要根据您将使用的字符串类别选择基本字符类型(charwchar_tchar16_tchar32_t)(分别为{{1} },std::stringstd::wstringstd::u16string):

std::u32string

匹配示例:

检查字符串是否与模式匹配:

typedef jpcre2::select<char> jp;
//Selecting char as the basic character type will require
//8 bit PCRE2 library where char is 8 bit,
//or 16 bit PCRE2 library where char is 16 bit,
//or 32 bit PCRE2 library where char is 32 bit.
//If char is not 8, 16 or 32 bit, it's a compile error.

匹配所有并获得匹配计数:

if(jp::Regex("(\\d)|(\\w)").match("I am the subject")) 
    std::cout<<"\nmatched";
else
    std::cout<<"\nno match";

获取编号的子字符串/捕获的组:

size_t count = 
jp::Regex("(\\d)|(\\w)","mi").match("I am the subject", "g");
// 'm' modifier enables multi-line mode for the regex
// 'i' modifier makes the regex case insensitive
// 'g' modifier enables global matching

获取已命名的子串/捕获组:

jp::VecNum vec_num;
count = 
jp::Regex("(\\w+)\\s*(\\d+)","im").initMatch()
                                  .setSubject("I am 23, I am digits 10")
                                  .setModifier("g")
                                  .setNumberedSubstringVector(&vec_num)
                                  .match();
std::cout<<"\nTotal match of first match: "<<vec_num[0][0];      
std::cout<<"\nCaptrued group 1 of first match: "<<vec_num[0][1]; 
std::cout<<"\nCaptrued group 2 of first match: "<<vec_num[0][2]; 

std::cout<<"\nTotal match of second match: "<<vec_num[1][0];
std::cout<<"\nCaptrued group 1 of second match: "<<vec_num[1][1];
std::cout<<"\nCaptrued group 2 of second match: "<<vec_num[1][2]; 

遍历所有匹配和子串:

jp::VecNas vec_nas;
count = 
jp::Regex("(?<word>\\w+)\\s*(?<digit>\\d+)","m")
                         .initMatch()
                         .setSubject("I am 23, I am digits 10")
                         .setModifier("g")
                         .setNamedSubstringVector(&vec_nas)
                         .match();
std::cout<<"\nCaptured group (word) of first match: "<<vec_nas[0]["word"];
std::cout<<"\nCaptured group (digit) of first match: "<<vec_nas[0]["digit"];

std::cout<<"\nCaptured group (word) of second match: "<<vec_nas[1]["word"];
std::cout<<"\nCaptured group (digit) of second match: "<<vec_nas[1]["digit"];

替换/替换示例:

//Iterating through numbered substring
for(size_t i=0;i<vec_num.size();++i){
    //i=0 is the first match found, i=1 is the second and so forth
    for(size_t j=0;j<vec_num[i].size();++j){
        //j=0 is the capture group 0 i.e the total match
        //j=1 is the capture group 1 and so forth.
        std::cout<<"\n\t("<<j<<"): "<<vec_num[i][j]<<"\n";
    }
}

替换为匹配评估器:

std::cout<<"\n"<<
///replace all occurrences of a digit with @
jp::Regex("\\d").replace("I am the subject string 44", "@", "g");

///swap two parts of a string
std::cout<<"\n"<<
jp::Regex("^([^\t]+)\t([^\t]+)$")
             .initReplace()
             .setSubject("I am the subject\tTo be swapped according to tab")
             .setReplaceWith("$2 $1")
             .replace();

您可以阅读完整的文档here

答案 2 :(得分:3)

Accept: application/json

将此指针与任何PCRE函数一起使用将导致未定义的行为。 PCRE2_SPTR pattern = (PCRE2_SPTR)std::string("([a-z]+)|\\s").c_str(); 临时文件在std::string定义的末尾被销毁,导致pattern悬挂。

我的建议是将pattern的类型更改为pattern,并在将参数传递给PCRE函数时调用std::string。在C ++ 11中这是一个非常快速的操作(你没有使用旧的GCC 4 ABI)。

还有一些PCRE的C ++包装器可以帮助您避免此类问题并使PCRE更易于使用,但我不支持Windows的支持状态。

答案 3 :(得分:0)

我不知道这是否仍然是你正在寻找的东西......但只是在这种情况下有帮助吗?

来自pcre2api手册页:

在Windows环境中,如果要将应用程序静态链接到非dll PCRE2库,则必须在包含pcre2.h之前定义PCRE2_STATIC。

答案 4 :(得分:0)

您可以按照以下步骤操作:

  1. 下载并安装cmake。
  2. 设置源文件夹位置和VS项目文件夹。
  3. 配置并选择您的VS版本。
  4. 完成配置过程后,您可以从列表中选择8位,16位和/或32位。
  5. 按生成,然后在项目文件夹中打开VS解决方案文件。这将在VS中打开解决方案。
  6. 大约有6个项目。突出显示pcre2._项目。转到首选项,并确保输出文件用于DLL。对pcre2posix项目重复此步骤。然后将greptest设置为可执行文件(可执行文件),另一个。
  7. 这时您可以尝试全部构建,但是您可能需要首先构建DLL,因为可执行文件依赖于它们(或它们的静态库)进行链接。
  8. 在成功构建所有6个项目之后,您应该在debug或release文件夹中拥有共享的/ static库和测试程序。

答案 5 :(得分:0)

这里有更多关于查尔斯·托马斯(Charles Thomas)的答案...

如果您是在Windows上使用C ++并使用PCRE2作为静态库构建的...在pcre2.h中,就有这个...

#if defined(_WIN32) && !defined(PCRE2_STATIC)
#  ifndef PCRE2_EXP_DECL
#    define PCRE2_EXP_DECL  extern __declspec(dllimport)
#  endif
#endif

_WIN32的定义是因为您在Windows上,但是您需要在pcre2.h的顶部定义PCRE2_STATIC,像这样...

#define PCRE2_STATIC 1

这使它在每个函数的前面放置了 extern“ C” ,而不是 extern __declspec(dllimport),因此您可以进行静态链接。