tzippy
tzippy

Reputation: 6638

Regex to match either one of two filename patterns

I am trying to match filenames using boost::regex and I have two kinds of patters:

  1. XYZsomestring
  2. XYsomestringENDING

The string somestring can be anything (>0 characters). The beginning of the filename is either XYZ or XY. If it is XY , there has to be the string ENDING that terminates the whole sequence. I tried to combine two regex with | but it doesnt work. This matches filenames with the first pattern:

(XYZ)(.*)

and this matches filenames with the second pattern:

(XY)(.*)(ENDING)

But when I combine them, only the first pattern matches:

((XYZ)(.*))|((XY)(.*)(ENDING))

All this is supposed to be case insensitive, that is why I use boost::regex::icase in the constructor. I have tried it without that icase, doesnt work either).

Any suggestions?

Upvotes: 2

Views: 1419

Answers (1)

nrussell
nrussell

Reputation: 18612

There may be simpler expressions but I think the regex ^xy(?(?!z).*ending$|.*$) should do it:

#include <iostream>
#include <string>
#include <boost/regex.hpp>

bool bmatch(const std::string& x, const std::string& re_) {
  const boost::regex re(re_, boost::regex::icase);
  boost::smatch what;
  return boost::regex_match(x, what, re);
}

int main()
{
  std::string re = "^xy(?(?!z).*ending$|.*$)";
  std::vector<std::string> vx = { "XYZ124f5sf", "xyz12345",
                                  "XY38fsj dfENDING", "xy4 dfhd ending",
                                  "XYZ", "XY345kENDI", "xy56NDING" };
  for (auto i : vx) {
    std::cout << "\nString '" << i;
    if (bmatch(i, re)) {
      std::cout <<
        "' was matched." << std::endl;
     } else {
      std::cout <<
        "' was not matched." << std::endl;
     }
  }

  return 0;
}

Here's a live demo.

Edit: Additionally, I think the regex ^xy(z.*|.*ending)$ should work as well.

Upvotes: 1

Related Questions