Lord Loh.
Lord Loh.

Reputation: 2477

How do I create a case insensitive regex to match file extensions?

I am trying to match all files that have the extension .nef - The match must be case insensitive.

regex e("(.*)(\\.NEF)",ECMAScript|icase);
...
if (regex_match ( fn1, e )){
    //Do Something
}

here fn1 is a string with a file name.

However, this "does something" only with files with .NEF (upper case) extensions. .nef extensions are ignored.

I also tried -

regex e("(.*)(\\.[Nn][Ee][Ff])");

and

regex e("(.*)(\\.[N|n][E|e][F|f])");

both of which resulted in a runtime error.

terminate called after throwing an instance of 'std::regex_error'
  what():  regex_error
Aborted (core dumped)

My code is compiled using -

g++ nefread.cpp -o nefread -lraw_r -lpthread -pthread -std=c++11 -O3

What am I doing wrong? This is my basic code. I want to extend it to match more file extensions .nef, .raw, .cr2 etc.

Upvotes: 2

Views: 6985

Answers (1)

Praetorian
Praetorian

Reputation: 109189

Your original expression is correct, and should produce the desired result. The problem is with the gcc implementation of <regex>, which is broken. This answer explains the historical reasons why it so, and also says that gcc4.9 will ship with a working <regex> implementation.

Your code works using Boost.Regex

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

int main()
{
    // Simple regular expression matching
    boost::regex expr(R"((.*)\.(nef))", boost::regex_constants::ECMAScript |
                                        boost::regex_constants::icase);
    //                ^^^           ^^
    // no need escape the '\' if you use raw string literals
    boost::cmatch m;

    for (auto const& fname : {"foo.nef", "bar.NeF", "baz.NEF"}) {
        if(boost::regex_match(fname, m, expr)) {
            std::cout << "matched: " << m[0] << '\n';
            std::cout << "         " << m[1] << '\n';
            std::cout << "         " << m[2] << '\n';
        }
    }
}

Live demo

Upvotes: 5

Related Questions