32#define PCRE2_CODE_UNIT_WIDTH 8
34#define PCRE_CASELESS PCRE2_CASELESS
35#define PCRE_MULTILINE PCRE2_MULTILINE
36#define PCRE_DOTALL PCRE2_DOTALL
37#define PCRE_EXTENDED PCRE2_EXTENDED
38#define PCRE_ERROR_NOMATCH PCRE2_ERROR_NOMATCH
100 pcre2_code_free(
fPriv->fPCRE);
103 pcre_free(
fPriv->fPCRE);
104 if (
fPriv->fPCREExtra)
105 pcre_free(
fPriv->fPCREExtra);
119 pcre2_code_free(
fPriv->fPCRE);
120 fPriv->fPCRE =
nullptr;
123 pcre_free(
fPriv->fPCRE);
124 fPriv->fPCRE =
nullptr;
125 if (
fPriv->fPCREExtra)
126 pcre_free(
fPriv->fPCREExtra);
127 fPriv->fPCREExtra =
nullptr;
170 const char *
m = modStr;
177 opts |= PCRE_CASELESS;
180 opts |= PCRE_MULTILINE;
189 opts |= PCRE_EXTENDED;
195 Error(
"ParseMods",
"illegal pattern modifier: %c", *
m);
229 pcre2_code_free(
fPriv->fPCRE);
232 pcre_free(
fPriv->fPCRE);
236 Info(
"Compile",
"PREGEX compiling %s",
fPattern.Data());
243 &errcode, &patIndex,
nullptr);
248 &errstr, &patIndex,
nullptr);
253 PCRE2_UCHAR errstr[256];
254 pcre2_get_error_message(errcode, errstr, 256);
257 throw std::runtime_error
258 (
TString::Format(
"TPRegexp::Compile() compilation of TPRegexp(%s) failed at: %d because %s",
259 fPattern.Data(), (
int)patIndex, errstr).Data());
261 Error(
"Compile",
"compilation of TPRegexp(%s) failed at: %d because %s",
262 fPattern.Data(), (
int)patIndex, errstr);
279 if (
fPriv->fPCREExtra)
280 pcre_free(
fPriv->fPCREExtra);
283 Info(
"Optimize",
"PREGEX studying %s",
fPattern.Data());
287 fPriv->fPCREExtra = pcre_study(
fPriv->fPCRE, 0, &errstr);
289 if (!
fPriv->fPCREExtra && errstr) {
290 Error(
"Optimize",
"Optimization of TPRegexp(%s) failed: %s",
304 const char *p = replacePattern;
308 while (state != -1) {
322 }
else if (!isdigit(p[1])) {
323 Error(
"ReplaceSubs",
"badly formed replacement pattern: %s",
324 replacePattern.
Data());
335 Info(
"ReplaceSubs",
"PREGEX appending substr #%d", subnum);
336 if (subnum < 0 || subnum > nrMatch-1) {
337 Error(
"ReplaceSubs",
"bad string number: %d",subnum);
339 const TString subStr = s(offVec[2*subnum],offVec[2*subnum+1]-offVec[2*subnum]);
361 pcre2_match_data *match_data;
362 match_data = pcre2_match_data_create_from_pattern(
fPriv->fPCRE,
nullptr);
365 match_data,
nullptr);
370 offVec, 3*nMaxMatch);
373 if (nrMatch == PCRE_ERROR_NOMATCH)
375 else if (nrMatch <= 0) {
376 Error(
"Match",
"pcre_exec error = %d", nrMatch);
378 pcre2_match_data_free(match_data);
386 PCRE2_SIZE *oVec = pcre2_get_ovector_pointer(match_data);
387 for (
int i = 0; i < 2 * nrMatch; ++i)
390 pos->Set(2*nrMatch, offVec);
394 pcre2_match_data_free(match_data);
449 for (
Int_t i = 0; i < nrMatch; i++) {
450 Int_t startp = pos[2*i];
451 Int_t stopp = pos[2*i+1];
452 if (startp >= 0 && stopp >= 0) {
453 const TString subStr = s(pos[2*i], pos[2*i+1]-pos[2*i]);
468 Bool_t doDollarSubst)
const
478 pcre2_match_data *match_data;
479 match_data = pcre2_match_data_create_from_pattern(
fPriv->fPCRE,
nullptr);
489 match_data,
nullptr);
493 offVec, 3*nMaxMatch);
496 if (nrMatch == PCRE_ERROR_NOMATCH) {
498 }
else if (nrMatch <= 0) {
499 Error(
"Substitute",
"pcre_exec error = %d", nrMatch);
504 PCRE2_SIZE *oVec = pcre2_get_ovector_pointer(match_data);
505 for (
int i = 0; i < 2 * nrMatch; ++i)
510 if (last <= offVec[0]) {
511 fin += s(last,offVec[0]-last);
517 ReplaceSubs(s, fin, replacePattern, offVec, nrMatch);
519 fin += replacePattern;
527 if (offVec[0] != offVec[1]) {
531 if (offVec[1] == s.
Length())
break;
532 offset = offVec[1]+1;
537 pcre2_match_data_free(match_data);
541 fin += s(last,s.
Length()-last);
580 return fPriv->fPCRE !=
nullptr;
630 const Int_t nrMatch =
r.Match(*
this,
"",
start,10,&pos);
632 *extent = pos[1]-pos[0];
655 return (*
this)(
r, 0);
854 typedef std::pair<int, int> MarkerLoc_t;
855 typedef std::vector<MarkerLoc_t> MarkerLocVec_t;
858 MarkerLocVec_t oMarks;
865 MarkerLocVec_t oCurrentTrailingEmpties;
868 Int_t nMatchesFound = 0;
874 while ((matchRes =
Match(s, nOffset)) &&
875 ((maxfields < 1) || nMatchesFound < maxfields)) {
879 oMarks.push_back(MarkerLoc_t(nOffset, nOffset + 1));
881 if (nOffset >= s.
Length())
889 if (!oCurrentTrailingEmpties.empty()) {
890 oMarks.insert(oMarks.end(),
891 oCurrentTrailingEmpties.begin(),
892 oCurrentTrailingEmpties.end());
893 oCurrentTrailingEmpties.clear();
895 oMarks.push_back(MarkerLoc_t(nOffset,
fMarkers[0]));
898 if (maxfields == 0) {
900 oCurrentTrailingEmpties.push_back(MarkerLoc_t(nOffset, nOffset));
902 oMarks.push_back(MarkerLoc_t(nOffset, nOffset));
909 for (
Int_t i = 1; i < matchRes; ++i)
916 if (nMatchesFound == 0) {
917 oMarks.push_back(MarkerLoc_t(0, s.
Length()));
921 else if (maxfields > 0 && nMatchesFound >= maxfields) {
922 oMarks[oMarks.size() - 1].second = s.
Length();
927 if (!last_empty || maxfields < 0) {
928 if (!oCurrentTrailingEmpties.empty()) {
929 oMarks.insert(oMarks.end(),
930 oCurrentTrailingEmpties.begin(),
931 oCurrentTrailingEmpties.end());
933 oMarks.push_back(MarkerLoc_t(nOffset, s.
Length()));
941 fMarkers[2*i + 1] = oMarks[i].second;
974 case 0 :
ret +=
'\\';
break;
975 case 'l': state = 1;
break;
976 case 'u': state = 2;
break;
977 case 'L': state = 3;
break;
978 case 'U': state = 4;
break;
979 case 'E': state = 0;
break;
980 default :
ret +=
'\\';
ret +=
c;
break;
985 case 0:
ret +=
c;
break;
986 case 1:
ret += (
Char_t) tolower(
c); state = 0;
break;
987 case 2:
ret += (
Char_t) toupper(
c); state = 0;
break;
990 default:
Error(
"TPMERegexp::Substitute",
"invalid state.");
1030 Printf(
" %d - %s", i,
operator[](i).Data());
int Int_t
Signed integer 4 bytes (int).
int Ssiz_t
String size (currently int).
char Char_t
Character 1 byte (char).
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int).
bool Bool_t
Boolean (0=false, 1=true) (bool).
const char Option_t
Option string (const char).
Error("WriteTObject","The current directory (%s) is not associated with a file. The object (%s) has not been written.", GetName(), objname)
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Array of integers (32 bits per element).
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
void Add(TObject *obj) override
Collectable string class.
Int_t fLastGlobalPosition
void ResetGlobalState()
Reset state of global match.
void * fAddressOfLastString
virtual void Print(Option_t *option="")
Print the regular expression and modifier options.
Int_t Split(const TString &s, Int_t maxfields=0)
Splits into at most maxfields.
TPMERegexp()
Default constructor. This regexp will match an empty string.
Int_t Substitute(TString &s, const TString &r, Bool_t doDollarSubst=kTRUE)
Substitute matching part of s with r, dollar back-ref substitution is performed if doDollarSubst is t...
TString operator[](Int_t)
Returns the sub-string from the internal fMarkers vector.
Int_t Match(const TString &s, UInt_t start=0)
Runs a match on s against the regex 'this' was created with.
void Reset(const TString &s, const TString &opts="", Int_t nMatchMax=-1)
Reset the pattern and options.
TString fLastStringMatched
void AssignGlobalState(const TPMERegexp &re)
Copy global-match state from 're; so that this regexp can continue parsing the string from where 're'...
void Compile()
Compile the fPattern.
Int_t SubstituteInternal(TString &s, const TString &replace, Int_t start, Int_t nMaxMatch0, Bool_t doDollarSubst) const
Perform pattern substitution with optional back-ref replacement.
Bool_t IsValid() const
Returns true if underlying PCRE structure has been successfully generated via regexp compilation.
TPRegexp & operator=(const TPRegexp &p)
Assignment operator.
UInt_t ParseMods(const TString &mods) const
Translate Perl modifier flags into pcre flags.
Int_t Match(const TString &s, const TString &mods="", Int_t start=0, Int_t nMaxMatch=10, TArrayI *pos=nullptr)
The number of matches is returned, this equals the full match + sub-pattern matches.
TObjArray * MatchS(const TString &s, const TString &mods="", Int_t start=0, Int_t nMaxMatch=10)
Returns a TObjArray of matched substrings as TObjString's.
static Bool_t fgThrowAtCompileError
Int_t ReplaceSubs(const TString &s, TString &final, const TString &replacePattern, Int_t *ovec, Int_t nmatch) const
Returns the number of expanded '$' constructs.
virtual ~TPRegexp()
Cleanup.
Int_t Substitute(TString &s, const TString &replace, const TString &mods="", Int_t start=0, Int_t nMatchMax=10)
Substitute replaces the string s by a new string in which matching patterns are replaced by the repla...
Int_t MatchInternal(const TString &s, Int_t start, Int_t nMaxMatch, TArrayI *pos=nullptr) const
Perform the actual matching - protected method.
TString GetModifiers() const
Return PCRE modifier options as string.
static Bool_t GetThrowAtCompileError()
Get value of static flag controlling whether exception should be thrown upon an error during regular ...
void Optimize()
Send the pattern through the optimizer.
static void SetThrowAtCompileError(Bool_t throwp)
Set static flag controlling whether exception should be thrown upon an error during regular expressio...
TStringToken(const TString &fullStr, const TString &splitRe, Bool_t retVoid=kFALSE)
Constructor.
Bool_t NextToken()
Get the next token, it is stored in this TString.
char & operator()(Ssiz_t i)
void ToLower()
Change string to lower-case.
TString(const char *a1, Ssiz_t n1, const char *a2, Ssiz_t n2)
Special constructor to initialize with the concatenation of a1 and a2.
const char * Data() const
TString & operator=(char s)
Assign character c to TString.
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const