Regex greedy operator (?) not working the same in android and ios

Please provide the following:

  1. SDK Version: “expo”: “~42.0.1”,
  2. Platforms(Android/iOS/web/all): andriod vs ios

I’m using the following regex:

// uri = file:///data/user/0/host.exp.exponent/cache/ExperienceData/%2540dedicatedmanagers%252Fmy-app/ImagePicker/eb116538-d9ce-4c75-9c51-d5f45b1318f6.jpg

let extension = uri.match(/\..*?$/i);

I’m trying to pull off the file extension from a uri returned by imagePicker. On iOS I get the dot (.) and the extension. The question mark (?) seems to be doing its job of stopping the any character star (*) from being greedy.

// extension = .jpg

However on Android, Its matching from the first dot (.)

// extension =  .exp.exponent/cache/ExperienceData/%2540dedicatedmanagers%252Fmy-app/ImagePicker/eb116538-d9ce-4c75-9c51-d5f45b1318f6.jpg

Any idea why this is happening? Is it a Javascript runtime compiler issue?

This reminds me of the joke: (No offense intended) :slight_smile:

Some people, when confronted with a problem, think “I know, I’ll use regular expressions.” Now they have two problems.

This does seem like something weird is going on with the JavaScript engine :astonished:
Are you using the default JavaScript Core, or Hermes as the JavaScript engine?

This regex doesn’t involve letters, so the “i” flag is unnecessary, but should not be a problem, of course.

You could avoid the greedy operator by using this regular expression instead:

let extension = uri.match(/\.[^.]*$/);

although you might want to be a bit more restrictive of the characters you accept in the extension.

By the way, how are you logging the extension? uri.match() should return an array. Not a string.

You could avoid the regex entirely if you don’t care what characters the extension contains like this:

const extension = uri.slice(uri.lastIndexOf('.') + 1);

Funny joke.

Great answer… thanks!

I ended up switching to the expression below, but I like your lastIndexOf way better so I’ll be using it!:

uri.match(/\.\w\w\w?$/i);

Note that in order to get the period I had to remove the +1 (granted I didn’t specify that in my question)

const extension = uri.slice(uri.lastIndexOf('.') );  // includes the period in the extension

How do I know if I’m using the default JavaScript Core, or Hermes as the JavaScript engine? I used the expo cli to create the project so I’d bet I’m using the default. I’m testing in the Expo Go app.

Finally, I am pulling the 0th index off of the regex match to get the extension (I didn’t show it in my question). And, because I use the end of string operator ($) in my regex, it should always only return an array with 1 match/value, if one is found.

Thanks again!

1 Like

Well, I should have paid more attention to the regex! :slight_smile:

Unless you did this you’re using JSC.

I’m glad you like it. :slight_smile: Just bear in mind that str.lastIndexOf('.') will return -1 if there is no ., and str.slice(-1) will return the last character of the string. So you might want to check if the index is >= 0 before using it.

Again, great advice. Thank you!

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.