1

I made this in C++ and I wanted to convert to JavaScript:

foreach (QString pattern, extensions) {
    regex.setPattern(QString("\\.%1").arg(pattern));
    regex.setPatternOptions(QRegularExpression::CaseInsensitiveOption);

    QRegularExpressionMatch match = regex.match(filename);

    if (! match.hasMatch()) continue;

    return pattern;
}

It means that foreach extensions (that is an array of extensions) as pattern create a pattern with that to be like: \\.png (for example). If there's a match it will return the found extension.

I tried to create exactly how I did in C++ but I don't know how to concatenate the returned string from the array to match

const filename = 'example.wutt'
const extensions = ['wutt', 'xnss']

extensions.forEach(pattern => {
  const match = filename.match(`\\.${pattern}`)
  console.log(match)
})

It does work but it's not case-insensitive as I can't put the i flag.

How can I do that (and if there's a solution using ES6)?

8
  • you are missing a closing tick mark, and a closing parenthesis Commented Oct 12, 2017 at 16:06
  • I edited my question and I didn't noticed that I removed, but I put it back. Commented Oct 12, 2017 at 16:07
  • if you run the code, it says that filename isn't defined Commented Oct 12, 2017 at 16:08
  • Also your c++ version returns a value in the loop, forEach in javascript won't break out of a forEach function if you return. Commented Oct 12, 2017 at 16:09
  • I didn't know that stackoverflow were this smart, I put the variable there as well Commented Oct 12, 2017 at 16:09

2 Answers 2

3

Have a look at How do you use a variable in a regular expression? for building the regex.

If you want to find the extension that matches, you can use Array#find:

const matchedExtension = extensions.find(
  ext => new RegExp(String.raw`\.${ext}$`, 'i').test(filename)
);

var extensions = ['png', 'jpeg'];

var filename = 'foo.png';

console.log(extensions.find(
  ext => new RegExp(String.raw `\.${ext}$`, 'i').test(filename)
));

Couple of notes:

  • String.raw is necessary to not treat \. as a string escape sequence but to pass it "as is" to the regular expression engine (alternative you could escape the \, but String.raw is cool).
  • $ at the end of the pattern ensures that the pattern is only matched at the end of the file name.
  • If you just want to know whether a pattern matches or not, RegExp#test is the preferred method.

If you are doing this a lot it makes sense to generate an array of regular expressions first (instead of creating the regex every time you call the function).

Sign up to request clarification or add additional context in comments.

3 Comments

Why use .find() instead of .filter()?
From the question: "If there's a match it will return the found extension." .filter would work I guess, but there is probably only a single extension that matches.
You rock! Thank you all <3
3

You can use RegExp constructor with "i" passed as second argument

extensions.forEach(pattern => {
    const match = filename.match(new RegExp(`\\.${pattern}$`, "i"));
    console.log(match);
})

4 Comments

Note that . matches any character. So If the filename was opngate.gif, it would match .png. You have to escape the . properly.
@FelixKling opngate.gif would not be matched using the pattern at Answer though you do have a point, see updated post.
Run "opngate.gif".match(new RegExp(`.png`, "i")) in your console ;)
@FelixKling You are correct. Ran test improperly. Was also missing $ within RegExp. [.]${pattern} could alternatively be used.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.