在c ++项目中使用pcre2

Sim*_*man 7 c++ pcre visual-c++ c++11

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

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

#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);
...
Run Code Online (Sandbox Code Playgroud)

首先文件" pcre2.h "不存在,所以我将pcre2.h.generic命名pcre2.h

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

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

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

更新
这不是一个导入库问题,pcre2.h没有librar(我不能在他们的发布位置看到).

Jah*_*hid 9

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

您需要选择基本字符类型(char,wchar_t,char16_t,char32_t根据您将使用字符串类)(分别为std::string,std::wstring,std::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.
Run Code Online (Sandbox Code Playgroud)

匹配示例:

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

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

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

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
Run Code Online (Sandbox Code Playgroud)

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

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]; 
Run Code Online (Sandbox Code Playgroud)

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

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"];
Run Code Online (Sandbox Code Playgroud)

迭代所有匹配和子串:

//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";
    }
}
Run Code Online (Sandbox Code Playgroud)

替换/替换示例:

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();
Run Code Online (Sandbox Code Playgroud)

替换为匹配评估器:

jp::String callback1(const jp::NumSub& m, void*, void*){
    return "("+m[0]+")"; //m[0] is capture group 0, i.e total match (in each match)
}
int main(){
    jp::Regex re("(?<total>\\w+)", "n");
    jp::RegexReplace rr(&re);
    String s3 = "I am ? ?? a string 879879 fdsjkll ? ? ? ? ? ? ? ? ? ? ???? ????? ?????";
    rr.setSubject(s3)
      .setPcre2Option(PCRE2_SUBSTITUTE_GLOBAL);
    std::cout<<"\n\n### 1\n"<<
            rr.nreplace(jp::MatchEvaluator(callback1));
            //nreplace() treats the returned string from the callback as literal,
            //while replace() will process the returned string
            //with pcre2_substitute()

    #if __cplusplus >= 201103L
    //example with lambda
    std::cout<<"\n\n### Lambda\n"<<
            rr.nreplace(
                jp::MatchEvaluator(
                    [](const jp::NumSub& m1, const jp::MapNas& m2, void*){
                        return "("+m1[0]+"/"+m2.at("total")+")";
                    }
                ));
    #endif
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

您可以在此处阅读完整的文档.

  • @ k-五:不。PCRE2库文档非常详细,如果您稍微阅读一下,事情就不会那么困难了。 (2认同)

Sim*_*man 7

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

  1. 从网站下载pcre2,(http://www.pcre.org/)
  2. 在Visual Studio 2015中,(或许还有其他人),创建一个空项目"Win32项目"并将其命名为pcre2.
  3. 将\ pcre2\src \中的所有文件复制到新创建的空项目中.
  4. 添加"NON-AUTOTOOLS-BUILD"中列出的所有文件,(位于基础文件夹中)
    • 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> C/C++> Precompiled Header>"Not Using Precompiled header"
  8. 选择项目,转到属性>预处理器>预处理器定义,然后选择下拉列表,并添加...
    • PCRE2_CODE_UNIT_WIDTH = 8
    • HAVE_CONFIG_H

应该编译和编译lib文件.