How can I replace string using NSRegularExpression in iOS? - ios

For example the regular expression is :
A(B)C
A,B,C all represent some string.I want all the string matches A(B)C replacing by B.
If the NSString is AABCAABCBBABC:
The answear will be ABABBBB.How to do that? Thank you.
I give a more specific example:
<script\stype="text/javascript"[\s\S]*?(http://[\s\S]*?)'[\s\S]*?</script>
The answer is some script mathes and http:// url matches .
I want to use each http:// url matches to replace each script matches. Did I explain it clearly?

One solution can be using stringByReplacingMatchesInString:
NSString *strText = #"AABCAABCBBABC";
NSError *error = nil;
NSRegularExpression *regexExpression = [NSRegularExpression regularExpressionWithPattern:#"ABC" options:NSRegularExpressionCaseInsensitive error:&error];
NSString *strModifiedText = [regexExpression stringByReplacingMatchesInString:strText options:0 range:NSMakeRange(0, [strText length]) withTemplate:#"B"];
NSLog(#"%#", strModifiedText);
Another solution can be using stringByReplacingOccurrencesOfString :
strText = [strText stringByReplacingOccurrencesOfString:#"ABC" withString:#"B"];

Related

multiple ????'s in regex cause error

I have a simple regex search and replace method. Everything works fine as expected, however when I was hammer testing yesterday the string I entered had "????" in it. this caused the regex to fail with the following error...
error NSError * domain: #"NSCocoaErrorDomain" - code: 2048 0x0fd3e970
upon further research I believe that it might be treating the question marks as a "trigraph". Chuck has a good explanation in this post.What does the \? (backslash question mark) escape sequence mean?
I tried to escape the sequence prior to creating the regex with this
string = [string stringByReplacingOccurrencesOfString:#"\?\?" withString:#"\?\\?"];
and it seem to stop the error but the search and replace no longer works. Here is the method I am using.
- (NSString *)searchAndReplaceText:(NSString *)searchString withText:(NSString *)replacementString inString:(NSString *)text {
NSRegularExpression *regex = [self regularExpressionWithString:searchString];
NSRange range = [regex rangeOfFirstMatchInString:text options:0 range:NSMakeRange(0, text.length)];
NSString *newText = [regex stringByReplacingMatchesInString:text options:0 range:range withTemplate:replacementString];
return newText;
}
- (NSRegularExpression *)regularExpressionWithString:(NSString *)string {
NSError *error = NULL;
NSString *pattern = [NSString stringWithFormat:#"\\b%#\\b", string];
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error];
if (error)
NSLog(#"Couldn't create regex with given string and options");
return regex;
}
My questions are; is there a better way of escaping this sequence? Is this a case of trigraphs, or another possibility? Or is a there a way in code of ignoring trigraphs or turning this off?
Thanks
My questions are; is there a better way of escaping this sequence?
Yes, you can properly escape any sequence of characters for a regular expression like this:
NSString* escapedExpression = [NSRegularExpression escapedPatternForString: aStringToEscapeCharactersIn];
EDIT
You don't have to run this on the whole expression. You can use NSString stringwithFormat: to insert escaped strings into REs with patterns in them e.g.
pattern = [NSString stringWithFormat: #"^%#(.*)", [NSRegularExpression escapedPatternForString: #"????"]];
will give you the pattern ^\?\?\?\?(.*)

Whats the quickest way to do lots of NSRange calls in a very long NSString on iOS?

I have a VERY long NSString. It contains about 100 strings I need to pull out of it, all randomly scattered throughout. They are all commonly are between imgurl= and &.
I could use NSRange and just loop through pulling out each string, but I'm wondering if there is a quicker was to pick out everything in a simple API call? Maybe something I am missing here?
Looking for the quickest way to do this. Thanks!
Using NSString methods componentsSeparatedByString and componentsSeparatedByCharactersInSet:
NSString *longString = some really long string;
NSArray *longStringComponents = [longString componentsSeparatedByString:#"imgurl="];
for (NSString *string in longStringComponents){
NSString *imgURLString = [[string componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"&"]] firstObject];
// do something with imgURLString...
}
If you feel adventurous then you can use regular expression. Since you said that the string you are looking is between imgurl and &, I assumed its a url and made the sample code to do the same.
NSString *str = #"http://www.example.com/image?imgurl=my_image_url1&imgurl=myimageurl2&somerandom=blah&imgurl=myurl3&someother=lol";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"(?:imageurl=)(.*?)(?:&|\\r)"
options:NSRegularExpressionCaseInsensitive
error:&error];
//should do error checking here...
NSArray *matches = [regex matchesInString:str
options:0
range:NSMakeRange(0, [str length])];
for (NSTextCheckingResult *match in matches)
{
//[match rangeAtIndex:0] <- gives u the whole string matched.
//[match rangeAtIndex:1] <- gives u the first group you really care about.
NSLog(#"%#", [str substringWithRange:[match rangeAtIndex:1]]);
}
If I were you, I will still go with #bobnoble method because its easier and simpler compared to regex. You will have to do more error checking using this method.

NSMutableString replaceOccurrencesOfString replacing whole words

Is there a way to use replaceOccurrencesOfString (from NSMutableString) to replace whole words?
For example, if I want to replace all occurrences of a fraction in a string, like "1/2", I'd like that to match only that specific fraction. So if I had "11/2", I would not want that to match my "1/2" rule.
I've been trying to look for answers to this already, but I am having no luck.
You could use word boundaries \b with Regex. This example matches the "1/2" at the start and the end of the example string, but neither of the middle options
// Create your expression
NSString *string = #"1/2 of the 11/2 objects were 1/2ed in (1/2)";
NSError *error = nil;
NSRegularExpression *regex =
[NSRegularExpression
regularExpressionWithPattern:#"\\b1/2\\b"
options:NSRegularExpressionCaseInsensitive
error:&error];
// Replace the matches
NSString *modifiedString =
[regex stringByReplacingMatchesInString:string
options:0
range:NSMakeRange(0, [string length])
withTemplate:#"HALF USED TO BE HERE"];

NSRegularExpression, specify case-sensitive match?

Is there a way using NSRegularExpression to specify that you want to do a case-sensitive search? I am trying to match the upper-case TAG "ACL" in the text below. The pattern I am using is simply:
// Pattern
[A-Z]+
// SearchText
<td align=\"left\" nowrap><font face=\"courier, monospace\" size=\"-1\">ACL*</font></td>
// Code:
NSString *textBuffer = #"<td align=\"left\" nowrap><font face=\"courier, monospace\" size=\"-1\">ACL*</font></td>";
NSString *pattern = #"([A-Z]+)";
NSRegularExpression *regExp = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil];
NSTextCheckingResult *result = [regExp firstMatchInString:textBuffer options:0 range:NSMakeRange(0, [textBuffer length])];
NSLog(#"OBJECT CLASS: %#", [textBuffer substringWithRange:[result range]]);
Output: (with case-Insensative I am getting the first "td" as expected, when what I really want is "ACL"
I know that NSRegularExpressionCaseInsensitive is wrong, I was hoping there would be a NSRegularExpressionCaseSensitive. Also there is a flagOption ?(i) that also specifies a case-insensitive search but again nothing for case-sensative. What am I missing?
Case sensitive is the default. Dont put the insensitive flag in there.

Replace occurences of string that contains any number

Say I have a string that contains a control code "\f3" (yes it is RTF). I want to replace that control code with another string. At the moment I am using [mutableString replaceOccurrencesOfString:#"\f3" withString:#"replacement string" options:0 range:NSMakeRange(0, [mutableString length])];
This works fine, however sometimes the code can be "\f4" or even "\f12" for example. How do I replace these strings? I could use replaceOccurrencesOfString for each, but the better way to do it is using wildcards, as it could be any number.
Regular expressions would do it.
Take a look at NSRegularExpression (iOS >= 4) and this page for how regular expressions work.
You will want something like:
// Create your expression
NSError *error = nil;
NSRegularExpression *regex =
[NSRegularExpression regularExpressionWithPattern:#"\\b\f[0-9]*\\b"
options:NSRegularExpressionCaseInsensitive
error:&error];
// Replace the matches
NSString *modifiedString = [regex stringByReplacingMatchesInString:string
options:0
range:NSMakeRange(0, [string length])
withTemplate:#"replacement string"];
WARNING : I've not tested my regaular expression and I'm not that great at getting them right first time; I just know that regular expressions are the way forward for you and it has to look something like that ;)

Resources