Emoji Numbers Passing RegEx - ios

Strange issue. I have a regex to limit what can be entered into a textfield. The pattern being used is as follows:
NSString *pattern = #"[0-9a-zA-Z'\\-\n ]";
This works great except while playing around with the Emoji keyboard I came across a case where the emoji graphic for the numbers 0-9 are being matched by the regex above. None of the other emoji characters including single letters pass the test. These are the graphics that have say the number 1 surrounded by a box sort of like it is on a button. How can I prevent that from passing the above pattern?
NSString *pattern = #"[0-9a-zA-Z'\\-\n ]";
NSError *error;
NSUInteger match = 1;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern: pattern options:0 error:&error];
if ([string length]>0) match = [regex numberOfMatchesInString:string options:0 range:NSMakeRange(0, 1)];
if (match != 1) return NO;

That emoji is a combination of a Unicode combining codepoint (for an enclosing "keycap" shape) and a normal numeral. http://www.fileformat.info/info/unicode/char/20e3/index.htm
If you want to exclude Unicode characters that can combine with your numerals, there are many possible combining marks that you'd need to look for (such as accent marks). Or you could verify that your string only has characters in the range you care about.

Below is how I wound up solving this. As I mentioned in a comment I am not thrilled for this approach as I am sure there is a regex way to solve. If one weren't already using regex I think this is fine, but since I am I think it would be cleaner to fully solve this with regex. If someone does have a regex answer that can combine with my regex from the OP, please do chime in.
if (![string canBeConvertedToEncoding:NSASCIIStringEncoding]) match = 0;
else
if ([string length]>0) match = [regex numberOfMatchesInString:string options:0 range:NSMakeRange(0, 1)];

Related

Remove Empty lines using Regular Expression

I'm new to iOS develoment, I have the data like this below and i want to remove all the empty lines, Please let me know what the pattern to be applied:
I have used the pattern as #"(\r\n)" and replaced it with #"", but it does not work. Please help me to sort out this issue
#EXTINF:-1 tvg-name="seedocs" tvg-logo="RT",RT
http://rt.ashttp14.visionip.tv/live/rt-global-live-HD/playlist.m3u8
#EXTINF:-1 tvg-name="hsn" tvg-logo="hsn",HSN TV
rtsp://hsn.mpl.miisolutions.net:1935/hsn-live01/_definst_/mp4:420p500kB31
#EXTINF:-1 tvg-name="us" tvg-logo="us",USTwit
http://bglive-a.bitgravity.com/twit/live/high
#EXTINF:-1 tvg-name="ALJAZEERA" tvg-logo="aljazeera",Aljazeera
rtmp://aljazeeraflashlivefs.fplive.net/aljazeeraflashlive-live/aljazeera_eng_high
#EXTINF:-1 tvg-name="bbc" tvg-logo="bbc",BBC World News
#EXTINF:-1 tvg-name="vevo" tvg-logo="vevo",Vevo
http://vevoplaylist-live.hls.adaptive.level3.net/vevo/ch1/06/prog_index.m3u8
#EXTINF:-1 tvg-name="vevo2" tvg-logo="vevo2",Vevo 2
http://vevoplaylist-live.hls.adaptive.level3.net/vevo/ch3/06/prog_index.m3u8
#EXTINF:-1 tvg-name="1HD" tvg-logo="1HD",1HD
rtmp://109.239.142.62/live/livestream3
[\r\n]+
You can use this instead.See demo.Replace by \n.
https://regex101.com/r/vV1wW6/26
NSString *string = #"Your multiline string";
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"[\r\n]+" options:NSRegularExpressionCaseInsensitive error:&error];
NSString *modifiedString = [regex stringByReplacingMatchesInString:string options:0 range:NSMakeRange(0, [string length]) withTemplate:#"\n"];
Search: (?:\r?\n){2,}
Replace: \r\n
\r?\n is both Windows and Linux compatible. {2,} means "two or more instances"
demo
If supported, you can use \R instead of \r?\n to include other types of Unicode newlines. This may be useful in the future, if not at present.
It is possible to use the NSString method
stringByReplacingOccurrencesOfString:withString:options:range:
with the option:
NSRegularExpressionSearch.
There is no need to use NSRegularExpression.
NSString *cleanText = [originalText stringByReplacingOccurrencesOfString:#"[\r\n]+" withString:#"\n" options:NSRegularExpressionSearch range:NSMakeRange(0, text.length)];
This will replace all runs of any combinations of \r and/or \n with a single \n thus elimination all bank lines.

Using a regex to remove a specific #tag in Objective-C

I am trying to parse a string in Objective-C to delete an exact match of a specific #tagged word. I can create a regular expression and delete a specific word without issue, but when I try to remove a string with a leading "#" it's not working.
Here's my code:
NSString *originalString = #"This is just a #test that isn't working";
NSString *hashTag = #"#test";
NSString *placeholder = #"\\b%#\\b";
NSString *pattern = [NSString stringWithFormat:placeholder, hashTag];
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil];
NSString *modifiedString = [regex stringByReplacingMatchesInString:originalString
options:0
range:NSMakeRange(0, [originalString length])
withTemplate:#""];
The issue is that even if the original string includes the string #test, it's not removed. If I swap "#test" with "test", everything works fine, but that's not what I'm trying to do. What am I missing?
Because there isn't a word character exists between a space and #. Both are non-word characters. So i suggest you to remove the starting \\b
NSString *placeholder = #"%#\\b";
OR
Use a negative lookbehind.
NSString *placeholder = #"(?<!\\S)%#\\b";
(?<!\\S) Negative lookbehind which asserts that there isn't a non-space character exists before the match.
To do an exact string match, i suggest you to use this #"(?<!\\S)%#(?!\\S)" regex. (?!\\S) Negative lookahead which asserts that the match won't be followed by a non-space character.
DEMO
is it even necessary to use a regex, would this function not suffice?
[yourstring stringByReplacingOccurrencesOfString:#"#test" withString:#""];

Removing \ from NSString (from escape sequences only)

I have tried (searching for) various possible solutions here on SO, in vain. Most of them simply replace all occurrences of backslashes, and don't respect backslashes that should otherwise be untouched.
For instance, if I have a Hi, it\'s me. How\'re you doing?, it should be Hi, it's me. How're you doing?. However, if someone tries to get creative with ASCII art, like
\\// \\// \\//
//\\ //\\ //\\
(WOW even SO won't let me add text as is, the above text needed extra backslashes to be displayed correctly.)
I cannot use [myString stringByReplacingOccurrencesOfString:#"\\" withString:#""]; since it will replace ALL backslashes. I do not want that.
I would like the string to be displayed as is.
NOTE: The strings in question here are values in NSDictionarys received as JSON from a web service. The use is in a service like a chat client, so it is important that text is handled correctly.
ULTRA IMPORTANT NOTE: I'm open to all ideas like library functions, regular expressions, human sacrifices, as long it gets the job done.
try this ...i cannot understand your question but it may help full for you,i think so
- (void)remove:(NSString*)str
{
NSString* const pattern = #"(\"[^\"]*\"|[^, ]+)";
NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:pattern
options:0
error:nil];
NSRange searchRange = NSMakeRange(0, [str length]);
NSArray *matches = [regex matchesInString:str
options:0
range:searchRange];
for (NSTextCheckingResult *match in matches) {
NSRange matchRange = [match range];
NSLog(#"%#", [str substringWithRange:matchRange]);
}
NSLog(#"%#",str);
}
call this method..
NSString* str = #"Hi, it\'s me. How\'re you doing?";
[self remove:str];
then the output is
Hi, it's me. How're you doing?

Regex issue in IOS Program

I am trying to get the following regex to work on ios in order to make sure the user is only inputting numbers and a dot. I am not able to get number of matches to be above 0. I have also tried NSRange one as well and that will give me 0 no matter what as well, so my regex is not working, even thought I am pretty sure it should with what I have there. Any suggestions.
The Code I wrote is here with errorRegex is defined in the .h file and regError is defined as well.
errorRegex = [NSRegularExpression regularExpressionWithPattern:#"[^0-9.]*"
options: NSRegularExpressionCaseInsensitive error:&regError];
NSUInteger rangeOfFirstMatch = [errorRegex numberOfMatchesInString:servAmount1TF.text
options:0 range:NSMakeRange(0, [servAmount1TF.text length])];
Why not use stock-standard c's regex.h ?
See an example here:
http://cboard.cprogramming.com/c-programming/117525-regex-h-extracting-matches.html
And more information here:
https://stackoverflow.com/a/422159/1208218
errorRegex is of type NSRegularExpression, but the error is of type UIButtonContent. This has all the halmarks of a memory error. Something in your code not going though a proper retain/release cycle.
I got a unit test to work with the expression #"[^0-9.]+"
- (void)testRE
{
NSError *regError = nil;
NSRegularExpression *errorRegex;
NSString *string;
NSUInteger count;
errorRegex = [NSRegularExpression regularExpressionWithPattern:#"[^0-9.]+"
options: NSRegularExpressionCaseInsensitive
error:&regError];
STAssertNil(regError, nil);
string = #"00.0";
count = [errorRegex numberOfMatchesInString:string
options:0
range:NSMakeRange(0, [string length])];
STAssertEquals(count, 0U, nil);
string = #"00A00";
count = [errorRegex numberOfMatchesInString:string
options:0
range:NSMakeRange(0, [string length])];
STAssertEquals(count, 1U, nil);
}
NSRegularExpression *errorCheckRegEx = [[NSRegularExpression alloc] initWithPattern:#"\\b^([0-9]+(\\.)?[0-9]*)$|^([0-9]*(\\.)?[0-9]+)$|^[0-9]*$|^([0-9]*(\\/)?[0-9]*)$\\b" options:NSRegularExpressionCaseInsensitive error:nil];
[match setArray: [errorCheckRegEx matchesInString:servAmount1TF.text options:0 range:NSMakeRange(0, [servAmount1TF.text length])]];
I figured out what I needed to do when I could finally get back to it so if anyone was interested this is what I came up with. The \b is just what ios uses in their regexp which is kind of dumb, but it will not work without that so I leave it there when it doesn't feel natural to do especially after ruby's example. This regular expression will get fractions, decimals -> .3; 2.3; 2; and does it from the front to end of the line. What I think might have been happening was the fact that I was not using the \b and also not matching correctly, which is the second line. Either way it works great now. Thanks for the help.

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