NSRegularExpression - Probleme with a Pattern

139 views Asked by At

i've wrote a little program to find a string in a string which works fine so far. But i have a problem with NSRegularExpression - i need the right Pattern for my special case and stuck.

NSString *strRegExp = [NSString stringWithFormat:@"?trunk/%@/%@/+\\([a-zA-Z0-9_\\-\\.])+/Host-1", inputstrse , inputstrsno];

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:strRegExp options:        NSRegularExpressionCaseInsensitive error:NULL];

NSArray *arrayOfAllMatches = [regex matchesInString:inputurl options:0 range:NSMakeRange(0, [inputurl length])];

The NSRegularExpression pattern should match string the look like this:

trunk/%@/%@/some-text-1/Host-1
trunk/test/1/5-text-text/Host-1

Where trunk/%@/%@/ and /Host-1 stays always the same. Only the part in the middle is variable and always looks like this:

NUMBER-Some-Text -> 5-Hello-World -> /trunk/test/1/5-hello-world/Host-1

I've tried it with different RegExp as you see here: "?trunk/%@/%@/+\([a-zA-Z0-9_\-\.])+/Host-1", but i still seems not to work, maybe someone can help me.

Maybe there is a Probleme when i build the pattern with:

 NSString *strRegExp = [NSString stringWithFormat:@"?trunk/%@/%@/+\\([a-zA-Z0-9_\\-\\.])+/Host-1", inputstrse , inputstrsno];

And use it later like that:

regularExpressionWithPattern:strRegExp

I hope someone can help me - i'm new to RegularExpressions.

2

There are 2 answers

3
Richard On BEST ANSWER

Generally, expressing a Regex as "I want to match a number of letters, then a dash, then a number" and so on is the easiest way to construct one. Also, using a tool such as http://www.regexr.com simplifies a lot.

From what I understand you want to match the following:

trunk/test/1/[some number]-[some text]-[some other text]/Host-1

If so, then the following regular expression should cut it:

trunk\/test\/1\/[0-9]*-[a-zA-Z]*-[a-zA-Z]*\/Host-1

It does the following:

  1. trunk\/test\/1\/: Match the constant string trunk/test/1/ (The backslashes are escapes)
  2. [0-9]*-: Match any number of digits followed by a -
  3. [a-zA-Z]*-: Match any number of letters followed by a -
  4. [a-zA-Z]*: Match any number of letters
  5. \/Host-1: Match the constant string /Host-1/

Here is a link to RegExr which you can use if you want to experiment with different input data or changes to the regex: http://regexr.com/39tgn

The following string was provided in the comments: trunk\test\/1\/.*\/Host-1. It's a bit less strict but does the job as well.

5
asontu On

I don't know Objective-C but your regex has a bunch of oddities, if I remove those I get something that I think you'd want to achieve.

Your first character is a ?, that can't be, it's a quantifier in regex that says something about the preceding character (or class or group). If it's the first character, there is no preceding char.

/+\\ <-- unsure what you were trying to do here, but it means '1 or more / followed by \'

[a-zA-Z0-9_\\-\\.] can be done much shorter like: [\w.-] and if you place the + within the parentheses it will capture the entire unknown string in capture group 1.

From comments: So %@ is a variable text, the first is always just letters, the 2nd is always just numbers. That would be [a-zA-Z]+ and \d+ respectively in a regex. But actually I would use [^/]+ (any character that isn't /) so that the code doesn't break when someone puts a different character in this path like trunk/this_text/4/.../Host-1 which would break on the _.

Combined this makes (changed after comments):

trunk/[^/]+/[^/]+/([\w.-]+)/Host-1

Regular expression visualization

Debuggex Demo

Now note that this is without escaping to get the proper string into the regex engine, but if Objective-C is anything like C# then a string started with @"..." doesn't need escaping.