Regex за съвпадение на един от двата модела на имена на файлове

Опитвам се да съпоставя имена на файлове с помощта на boost::regex и имам два вида шаблони:

  1. XYZsomestring
  2. XYsomestringENDING

Низът somestring може да бъде всичко (>0 знака). Началото на името на файла е XYZ или XY. Ако е XY, трябва да има низ ENDING, който завършва цялата последователност. Опитах се да комбинирам два регулярни израза с |, но не работи. Това съвпада с имена на файлове с първия модел:

(XYZ)(.*)

и това съвпада с имена на файлове с втория модел:

(XY)(.*)(ENDING)

Но когато ги комбинирам, само първият шаблон съвпада:

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

Всичко това трябва да е без значение за главни и малки букви, затова използвам boost::regex::icase в конструктора. Опитах го без това icase, също не работи).

Някакви предположения?


person tzippy    schedule 19.06.2015    source източник
comment
Можете ли да дадете някои конкретни примери, които съвпадат и не? И по-добре малък код, който демонстрира проблема, защото самият регулярен израз изглежда правилен.   -  person Petr    schedule 19.06.2015
comment
@tzippy, низът XYZENDING трябва да дава съвпадение?   -  person    schedule 19.06.2015
comment
Опитайте ((XY)(.*)(ENDING))|((XYZ)(.*))   -  person Wiktor Stribiżew    schedule 19.06.2015
comment
@stribizhev , не. На низ XYZ не дава истинския резултат. Вероятно е по-добре да използвате + вместо *   -  person    schedule 19.06.2015


Отговори (1)


Може да има по-прости изрази, но мисля, че регулярният израз ^xy(?(?!z).*ending$|.*$) трябва да го направи:

#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;
}

Ето демонстрация на живо.

Редактиране: Освен това мисля, че регулярният израз ^xy(z.*|.*ending)$ също трябва да работи.

person nrussell    schedule 19.06.2015