2

Hi to all overflowers,

I'm scratching my head around putting a regular expression inside an NSPredicate.

I would like to move all our thumbnails from Documents directory into Caches directory and catch em'all I've created this regex: _thumb(@[2-3]x)?\.jpg.

Here on regex101.com you can see the above regex working with this test data:

grwior_thumb.jpg          <- match
grwior.jpg
vuoetrjrt_thumb@2x.jpg    <- match
vuoetrjrt.jpg
hafiruwhf_thumb.jpg       <- match
hafiruwhf_thumb@2x.jpg    <- match
hafiruwhf_thumb@3x.jpg    <- match
hafiruwhf.jpg

But when I put it in the code it's not matching anything:

NSError *error = nil;
NSFileManager *fileManager = [NSFileManager defaultManager];

// Find and move thumbs to the caches folder
NSArray<NSString *> *mediaFilesArray = [fileManager contentsOfDirectoryAtPath:documentsPath error:&error];

NSString *regex = @"_thumb(@[2-3]x)?\\.jpg";
NSPredicate *thumbPredicate = [NSPredicate predicateWithFormat: @"SELF ENDSWITH %@", regex];

NSArray<NSString *> *thumbFileArray = [mediaFilesArray filteredArrayUsingPredicate:thumbPredicate];

thumbFileArray has always 0 elements...

What am I doing wrong?

Nicolas Miari
  • 16,006
  • 8
  • 81
  • 189
Shebuka
  • 3,148
  • 1
  • 26
  • 43

2 Answers2

2

Use MATCHES rather than ENDSWITH, as ENDSWITH does not treat the expression as a regular expression, but make sure you match all the chars from the start of the string, too, as MATCHES requires a full string match, so you need to somehow match the chars before the _.

Use

NSString *regex = @".*_thumb(@[23]x)?\\.jpg";

And then

[NSPredicate predicateWithFormat: @"SELF MATCHES %@", regex]

The .* will match any 0+ chars other than line break chars, as many as possible.

Note that if you just want to match either 2 or 3, you might as well write [23], no need for a - range operator here.

You may also replace (@[23]x)? with (?:@[23]x)?, i.e. change the capturing group to a non-capturing, since you do not seem to need the submatch to be accessible later. If you do, keep the optional capturing group.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • 1
    Looking at LIKE and MATCHES string comparison operators I've assumed that others were regex capable and only in need of proper escape. You never stop learning... Also, thanks for the suggestion to use a non-capturing group. – Shebuka Jul 25 '17 at 10:30
1

The problem is with ENDSWITH.

ENDSWITH
The left-hand expression ends with the right-hand expression.
MATCHES
The left hand expression equals the right hand expression using a regex-style comparison according to ICU v3

What you need is

NSString *regex = @".+_thumb(@[2-3]x)?\\.jpg";
NSPredicate *thumbPredicate = [NSPredicate predicateWithFormat: @"SELF MATCHES %@", regex];
xiangxin
  • 409
  • 6
  • 18