Regexp, iterators, libraries, class definitions

Hi all,
I’m trying to run some code on a series of files. To extract the files I’d like to run the code on, i’m trying to match some vales in the filename with a regular expression.
I have used the same regular expression submatch extraction code within a compiled class successfully, but when trying to use it in a macro, it doesn’t work. I have a feeling this is due to dictionaries, definitions etc, but i’m not really clear on what’s missing or how to include it.

my macro is as follows: #include <string> #include <regex> void DoReconstruction(TString fname;){ std::match_results<string::const_iterator> submatches; // data file names are of the format "DataT44S33p1.root" std::regex theexpression (".*?DataT([0-9]+)S([0-9]+)[pP]([0-9]+).*"); std::regex_match ((std::string)fname, submatches, theexpression); std::string tval = (std::string)submatches[1]; if(tval==44){ // do code on this file } }
The error i’m getting is

Error: Symbol match_results is not defined in current scope DoReconstruction.C:49: Error: Symbol const_iterator is not defined in current scope DoReconstruction.C:49: Error: Symbol submatches is not defined in current scope DoReconstruction.C:49:

Hi. I suspect the problem is the semicolon [;] in the argument of the function in your macro. The following works nicely for me:

#include <string>
#include <regex>
void DoReconstruction(TString fname){
  std::match_results<string::const_iterator> submatches;
  // data file names are of the format "DataT44S33p1.root"
  std::regex theexpression (".*?DataT([0-9]+)S([0-9]+)[pP]([0-9]+).*");
  std::regex_match ((std::string)fname, submatches, theexpression);
  std::string tval = (std::string)submatches[1];
  if(tval == "44"){
     std::cout << "do code on this file" << std::endl;
  }
}

It produces:

   -----------------------------------------------------------------------
  | Welcome to ROOT 6.07/07                           http://root.cern.ch |
  |                                          (c) 1995-2016, The ROOT Team |
  | Built for macosx64                                                    |
  | From heads/master@v6-07-07-aliceml-30-gf74a6c9, May 20 2016, 16:19:53 |
  | Try '.help', '.demo', '.license', '.credits', '.quit'/'.q'            |
   -----------------------------------------------------------------------

root [0] .x DoReconstruction.C("DataT44S33p1.root") 
do code on this file
root [1] .q

Thanks for the suggestion mato.
The semicolon was actually a typo i made while simplifying the code for posting. Running that snippet I receive:

root [0] .x DoReconstruction.C("DataT44S33p1.root")
.Error: Symbol match_results is not defined in current scope  DoReconstruction.C:4:
Error: Symbol const_iterator is not defined in current scope  DoReconstruction.C:4:
Error: Symbol submatches is not defined in current scope  DoReconstruction.C:4:
(const int)0
*** Interpreter error recovered ***
root [1] .

as before

I’m kinda shooting in the dark here, but… I’m using root v5.34.32 remotely on a virtual machine at fermilab, which perhaps wasn’t compiled with c++11…unfortunately my macro contains a fair bit of other code that breaks if i try to compile it. (i think the difference is due to rootish macro code vs standalone c++ code, rather than indicative of errors)

Don’t use ROOT 5 for this. CINT does not support C++11. For this you must use ROOT 6.

It isn’t my system, i don’t think i can choose.

In this case, you could perhaps use the TRegexp class. See root.cern.ch/doc/master/classTRegexp.html

I’ve had a look at that page, but i don’t see how to extract the submatches… all i can see is an ‘index’ member function that seems to require me to specify the start point and length of my match, and returns an index???

Yes. Unfortunately the functionality provided by TRegexp is quite basic.

H’mm. :confused: Well, in the end I was able to upgrade to ROOT 6, but unfortunately I can’t test to see whether i can now use c++11 regexes because the code won’t run - it complains that my class isn’t defined.

The class definition is invoked with a line ‘gSystem->Load(“myLib.so”)’. When i tried that line in an interactive session it complained it couldn’t find the dictionary. It seems like that’s due to changes between v5.34 and v6 - and is easily solved by copying the .pcm to the same folder as the .so. I can then call gSystem->Load and it works. But this line in my macro just doesn’t seem to be getting executed. Calling the macro from shell (root ‘mymacro.C’) fails (can’t find class). Using ‘.x mymacro.C’ from a fresh root prompt also fails. But if call ‘gSystem->Load(); THEN .x mymacro.C’, it’s fine. I Even though this line is in mymacro.C. … :neutral_face:

As fun as all this is, for now, i’ve given up and moved back to ROOT 5.34… so that i can continue battling another problem. ](*,)

I appreciate the help all the same, so thanks again mato.

Hi. Yes, there is a difference with respect loading libraries in macros between 5 and 6. If you add the following line in your macro it should work:


R__LOAD_LIBRARY(myLib)

Pere

[quote=“mato”]Hi. Yes, there is a difference with respect loading libraries in macros between 5 and 6. If you add the following line in your macro it should work:


R__LOAD_LIBRARY(myLib)

Pere[/quote]

Fantastic! Including that I can now use ROOT 6. Thanks Pere. :smiley: