Objective C. Regular expression to eliminate anything after 3 dots - objective-c

I wrote the following code to eliminate anything after 3 dots
currentItem.summary = #"I am just testing. I am ... the second part should be eliminated";
NSError * error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"(.)*(/././.)(.)*" options:0 error:&error];
if(nil != regex){
currentItem.summary = [regex stringByReplacingMatchesInString:currentItem.summary
options:0 range:NSMakeRange(0, [currentItem.summary length])
withTemplate:#"$1"];
}
However, my input and output are the same. The correct output should be "I am just testing. I am".
I was trying to do this using regular expression because I have a database of other regular expressions that I run on the string. I know the performance might not be as good as a plain text find or replace but the strings involved are short. I also tried using "\" to escape the dots in the regex, but I was getting a warning.
There is another question with a similar topic but the match strings are not for objective c.

This is much easier and will accomplish what you want:
NSRange range = [currentItem.summary rangeOfString:#"..."];
if (range != NSNotFound) {
currentItem.summary = [currentItem.summary substringToIndex:range.location];
}

You have forward slashes, /, instead of backward slashes, \, in your pattern. Also if you wish to match everything before the three dots you should use (.*) - tag everything matched by the enclosed .*. (The other parentheses in the pattern are redundant.)

Nice alternative:
NSScanner *scanner = [NSScanner scannerWithString:currentItem.summary];
[scanner scanUpToString:#"..." intoString: &currentItem.summary];

My recommended regex for your problem:
regularExpressionWithPattern:#"^(.*)\\s*\\.{3}.*$"
Main differences between this one and yours:
uses backslashes to escape special chars
uses ^ and $ to anchor at the beginning and end of the string
only captures the interesting section with ()
strips whitespace before the ... by ignoring any number of whitespace chars (\s*).

After correcting the slashes and other improvements, my final expression is:
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"^(.*)\\.{3}.*$"
options:0
error:&error];

Related

Objective-C Find first matching regular expression in string

I have a task with regular expressions. I have a list of NSRegularExpression objects with different patterns. Also I have a NSString object to define a source. I need to find which regular expression (from the given list) matches for the BEGINNING of source.
Is there a way to do it with Objective-C?
For example:
Expressions patterns
[a-z]
[A-Z]
[1-9]
source
Hello32
Result
Expression no 2 fits for the beginning of source, because of letter H.
Why don't you just try them out?
NSString *testString = #"Hello";
NSArray *patterns = #[
#"[a-z]",
#"[A-Z]",
#"[1-9]",
];
for (NSString *pattern in patterns) {
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:0
error:NULL];
BOOL matchAtStart = [regex rangeOfFirstMatchInString:testString
options:0
range:(NSRange){0, testString.length}].location == 0;
NSLog(#"'%#': %#", pattern, #(matchAtStart));
}
You can prepend \A(?: and append ) to each pattern to force them to match at the beggining of the string. The patterns provided as example would become:
\A(?:[a-z])
\A(?:[A-Z])
\A(?:[1-9])
\A is an anchor to the beggining of the string (behaves exactly like ^ when the Multiline flag is not set).

Objective C Regex?

I'm trying to parse a 7-digit number from a page's source code and the pattern that I look for is
/nnnnnnn"
where "n" is a digit. I'm trying with the following regex and in a regex test site it works, but not in obj-c. Is it possible that I'm passing the wrong option or something?
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"/\d\d\d\d\d\d\d\">" options:NSRegularExpressionSearch error:nil];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:contents
options:0
range:NSMakeRange(0, [contents length])];
You should double the backslashes in front of your ds, like this:
#"/\\d\\d\\d\\d\\d\\d\\d\">"
Backslash is a special character inside a string literal: the character after it is interpreted differently. In order for the regex engine to see a backslash, you need two slashes in the literal.

Objective-C: Parsing String into an Array under Special Circumstances

I have a string:
[{"id":1,"gameName":"arizona","cost":"0.5E1","email":"hi#gmail.com","requests":0},{"id":2,"gameName":"arizona","cost":"0.5E1","email":"hi#gmail.com","requests":0},{"id":3,"gameName":"arizona","cost":"0.5E1","email":"hi#gmail.com","requests":0}]
However, I would like to parse this string into an array such as:
[{"id":1,"gameName":"arizona","cost":"0.5E1","email":"hi#gmail.com","requests":0},
{"id":2,"gameName":"arizona","cost":"0.5E1","email":"hi#gmail.com","requests":0},
{"id":3,"gameName":"arizona","cost":"0.5E1","email":"hi#gmail.com","requests":0}]
This array is delimited by the comma in between the curly braces: },{
I tride usign the command
NSArray *responseArray = [response componentsSeparatedByString:#","];
but this separates the string into values at EVERY comma, which is not desirable.
Then I tried using regex:
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\\{.*\\}" options:NSRegularExpressionCaseInsensitive error:&error];
NSArray *matches = [regex matchesInString:response options:0 range:NSMakeRange(0, [response length])];
which found one match: starting at the first curly brace to the last curly brace.
I was wondering if anyone new how to solve this problem efficiently?
This string seems to be valid JSON. Try a JSON parser: NSJSONSerialization
I agree with H2CO3's suggestion to use a parser where possible.
But looking at your attempted regex, it looks like you just need to make it non-greedy, i.e.
#"\\{.*?\\}"
^
|
Add this question mark for non-greedy matching.
Of course, this will fail if you have deeper levels of (what I assume to be) nested arrays. Go with the JSON parser!

NSRegularExpression escaping parentheses

I'm using regular expressions to find some values in a string, however, what I'm trying to find looks something like this:
Dealt to SanderDecler [2s 5d]
But I can't seem to find a way to escape these square brackets, I've had the same problem with parentheses earlier. I've tried to escape them like this \( or \[, but that didn't give any matches. So I just replaced that with a dot, and it did match, however, that doesn't seem like the best way to do it, and I can imagine it's better for performance to specify the exact character too...
So my question is, how can I match parantheses and square brackets?
Here's how my code looks like now, this is working, but non-optimal:
NSString *expression =
#"^Dealt to (.{1,12}) .([0-9TJKQA][cdhs]) ([0-9TJKQA][cdhs]).";
NSRegularExpression *regex =
[NSRegularExpression regularExpressionWithPattern:expression
options:NSRegularExpressionAnchorsMatchLines
error:nil];
for (NSTextCheckingResult *result in [regex matchesInString:history options:NSMatchingReportCompletion range:NSMakeRange(0, history.length)])
{
NSLog(#"%#", [history substringWithRange:[result rangeAtIndex:0]]);
}
Try this:
#"^Dealt to (.{1,12}) \\[([0-9TJKQA][cdhs]) ([0-9TJKQA][cdhs])\\]"

Why NSRegularExpression says that there are two matches of ".*" in the "a" string?

I'm very happy that Lion introduced NSRegularExpression, but I can't understand why the pattern .* matches two occurrences in a string like "a" (text can be longer).
I was using following code:
NSError *anError = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#".*"
options:0
error:&anError];
NSString *text = #"a";
NSUInteger counter = [regex numberOfMatchesInString:text
options:0
range:NSMakeRange(0, [text length])];
NSLog([NSString stringWithFormat:#"counter = %u", counter]);
Output from the console is:
2011-07-27 22:03:27.689 Regex[1930:707] counter = 2
Can anyone explain why that is?
The regular expression .* matches zero or more characters. Thus, it will match the empty string as well as a and as such there are two matches.
Mildly surprised that it didn't match 3 times. One for the "" before the "a", one for the "a" and one for the "" after the "a".
As has been noted, use a more precise pattern; including anchors (^ and/or $) might also change the behaviour.
No-one has asked, but why would you want to do this anyway?
The documents on NSRegularExpression say the following:
Some regular expressions [...] can
successfully match a zero-length range, so the comparison of the
resulting range with {NSNotFound, 0} is the most reliable way to
determine whether there was a match or not.
I more reliable way to get just one match would be to change the expression to .+