Using pcre2 in a C ++ project

I am considering using pcre2 in my simple C ++ application (I am using vs2015). (I look at various regex libraries, and the general feeling is that pcre / pcre2 are the most flexible)

First I downloaded pcre2 from the official place, ( http://sourceforge.net/projects/pcre/files/pcre2/10.20/ ) and created a very simple example.

#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("([az]+)|\\s").c_str(); ... int errorcode; PCRE2_SIZE erroroffset; pcre2_code *re = pcre2_compile(pattern, PCRE2_ZERO_TERMINATED, PCRE2_ANCHORED | PCRE2_UTF, &errorcode, &erroroffset, NULL); ... 

First of all, the file "pcre2.h" does not exist, so I renamed pcre2.h.generic to pcre2.h

But then I get linker errors with unresolved external ones.

I assume that I need to include one or more files from the source in the project. But I don’t want to just add files, not knowing that all this does.

Can someone give some simple steps to successfully create a project using pcre2?

UPDATE
This is not an import library problem, pcre2.h does not come with a librator (not the one I can see in their release location).

+5
source share
4 answers

If someone wants to create a library using visual studio

  • Download pcre2 from the website, ( http://www.pcre.org/ )
  • in Visual Studio 2015 (and possibly others), create an empty Win32 Project project and name it pcre2.
  • Copy all the files in \ pcre2 \ src \ to the newly created empty project.
  • Add all the files listed in "NON-AUTOTOOLS-BUILD" (located in the base folder)
    • pcre2_auto_possess.c
    • pcre2_chartables.c
    • pcre2_compile.c
    • pcre2_config.c
    • etc...
  • Rename the file config.h.generic to config.h
  • Add the config.h file to the project.
  • In your project, select the entire * .c file Go Properties> C / C ++> Precompiled Header> "Do Not Use Precompiled Header"
  • Select the project, choose Properties> Preprocessor> Preprocessor Definition, and select the drop-down list and add ...
    • PCRE2_CODE_UNIT_WIDTH = 8
    • HAVE_CONFIG_H

Compile and the lib file should be created normally.

+5
source

If you don't mind using a wrapper, here's mine: JPCRE2

You need to select the main character type ( char , wchar_t , char16_t , char32_t ) according to the string classes that you will use (respectively 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 a compile error. 

Matching examples:

Check if the string matches the pattern:

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

Match everything and get a 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 

Get numbered substrings / captured groups:

 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]; 

Get substrings / captured groups:

 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"]; 

Iterate over all matches and substrings:

 //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 ie the total match //j=1 is the capture group 1 and so forth. std::cout<<"\n\t("<<j<<"): "<<vec_num[i][j]<<"\n"; } } 

Replace / replace examples:

 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(); 

Replace with conformity assessment:

 jp::String callback1(const jp::NumSub& m, void*, void*){ return "("+m[0]+")"; //m[0] is capture group 0, ie 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; } 

You can read the full documentation here .

+6
source
 PCRE2_SPTR pattern = (PCRE2_SPTR)std::string("([az]+)|\\s").c_str(); 

Using this pointer with any of the PCRE functions will result in undefined behavior. The temporary code std::string destroyed at the end of the pattern definition, causing the pattern hang around.

My recommendation is to change the pattern type to std::string and call c_str() when passing arguments to the PCRE function. This is a very fast operation in C ++ 11 (and you are not using the old GCC 4 ABI).

There are also several C ++ shells for PCRE that can help you avoid such problems and make PCRE easier to use, but I do not support Windows support.

+3
source

I don’t know if this is still what you are looking for or not ... but in any case does it help?

On pcre2api man page:

On a Windows environment, if you want to statically link an application to the PCRE2 non-dll library, you must define PCRE2_STATIC before enabling pcre2.h.

0
source

All Articles