Regex to reject sequence of Digits - objective-c

I need to validate phone number. Below is the code snippet
-(BOOL) validatePhone:(NSString*) phoneString
{
NSString *regExPattern = #"^[6-9]\\d{9}$"; ORIGINAL
// NSString *regExPattern = #"^[6-9](\\d)(?!\1+$)\\d*$";
NSRegularExpression *regEx = [[NSRegularExpression alloc] initWithPattern:regExPattern options:NSRegularExpressionCaseInsensitive error:nil];
NSUInteger regExMatches = [regEx numberOfMatchesInString:phoneString options:0 range:NSMakeRange(0, [phoneString length])];
NSLog(#"%lu", (unsigned long)regExMatches);
if (regExMatches == 0) {
return NO;
}
else
return YES;
}
I want to reject phone number that is in sequnce example
9999999999, 6666677777

It seems you want to disallow 5 and more identical consecutive digits.
Use
#"^[6-9](?!\\d*(\\d)\\1{4})\\d{9}$"
See the regex demo
Details
^ - start of string
[6-9] - a digit from 6 to 9
(?!\d*(\d)\1{4}) - a negative lookahead that fails the match if, immediately to the right of the current location, there is
\d* - 0+ digits
(\d) - a digit captured into Group 1
\1{4} - the same digit as captured in Group 1 repeated four times
\d{9} - any 9 digits
$ - end of string (replace with \z to match the very end of string do disallow the match before the final LF symbol in the string).
Note that \d is Unicode aware in the ICU regex library, thus it might be safer to use [0-9] instead of \d.

Related

Matching the entire input with Regex, Objective-C

I have an application that communicates with a serial port. I am looking to create a packet descriptor with regex that can recognize the expression.
The string is !$S0, 0, 48, 3and I want the regex to recognize any digit.
- (IBAction)getStatus:(id)sender
{
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:#"[(!$S\\d,\\s\\d,\\s\\d,\\s\\d)]" options:0 error:0];
self.getStatus = [[ORSSerialPacketDescriptor alloc] initWithRegularExpression:regex maximumPacketLength:20 userInfo:nil];
[self.serialPort startListeningForPacketsMatchingDescriptor:self.getStatus];
NSString *command = #"$S";
command = [command stringByAppendingString:[self lineEndingString]];
NSData *dataToSend = [command dataUsingEncoding:NSUTF8StringEncoding];
[self.serialPort sendData:dataToSend];
}
I expect it to pull the whole response so that I can process the string here:
- (void)serialPort:(ORSSerialPort *)serialPort didReceivePacket:(NSData *)packetData matchingDescriptor:(ORSSerialPacketDescriptor *)descriptor {
NSString *asciString = [[NSString alloc] initWithData:packetData encoding:NSASCIIStringEncoding];
NSLog(#"package[asci]: %#", asciString);
if (descriptor == self.getStatus) {
}
}
Any help would be appreciated.
You may use
#"!\\$S\\d+(?:,\\s+\\d+){3}"
Enclose with ^ (start of string) and $ (end of string) if you plan to match the string exactly:
#"^!\\$S\\d+(?:,\\s+\\d+){3}$"
See the regex demo
Details
^ - start of string
! - a !
\\$ - a $ symbol (must be escaped)
S - an S letter
\\d+ - 1 or more digits
(?:,\\s+\\d+){3} - 3 consecutive sequences of:
, - a comma
\\s+ - 1 or more whitespaces
\\d+ - 1 or more digits
$ - end of string.

how to replace in string using regex

I have below as string
name : abc,
position : 2
I want to make replace so that the string becomes as below
name : "abc",
position : 2
What change I want to do is abc will have double quotes so abc becomes "abc".
Note: abc is dynamic, it can be anything as below.
name : Test,
position : 2
name : Great,
position : 2
name : developers,
position : 2
Any idea how this can be done?
I suggest using \\b(name\\s*:\\s*)(.+), pattern and replace with $1"$2",:
NSError *error = nil;
NSString *myText = #"name : abc,\nposition : 2";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\\b(name\\s*:\\s*)(.+)," options:nil error:&error];
NSString *modifiedString = [regex stringByReplacingMatchesInString:myText options:0 range:NSMakeRange(0, [myText length]) withTemplate:#"$1\"$2\","];
NSLog(#"%#", modifiedString);
See the Objective-C demo
Details:
\\b - a leading word boundary
(name\\s*:\\s*) - Group 1 matching name, 0+ whitespaces, : and 0+ whitespaces again
(.+) - any 0+ chars other than line break chars as many as possible
, - comma
The replacement pattern - $1"$2", - inserts Group 1 contents, ", Group 2 contents and ",.
See the regex demo.

How to use RegEx to support single line mode in textview?

I set my custom textview to support regExPatternValidation = #"^[0-9]{0,10}$";
and use the following method to accomplish my validation:
+ (BOOL)validateString:(NSString *)string withRegExPattern:(NSString *)regexPattern
{
BOOL doesValidate = NO;
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexPattern
options:NSRegularExpressionCaseInsensitive
error:&error];
if (error)
{
DDLogError(#"%#:%# : regular expression error: [%#]", THIS_FILE, THIS_METHOD, error.description);
return doesValidate;
}
NSRange textRange = NSMakeRange(0, string.length);
NSUInteger regExMatches = [regex numberOfMatchesInString:string options:NSMatchingReportCompletion range:textRange];
if (regExMatches > 0 && regExMatches <= textRange.length+1)
{
doesValidate = YES;
}
else
{
doesValidate = NO;
}
return doesValidate;
}
One of its purposes is to control single or multi line modes. For some strange reason, when I hit the Return key (\n), the numberOfMatchesInString: still returns 1 match. Even though my regex pattern has no inclusion to support \n characters.
Is it possible to accomplish this feature using regex in Objective-C?
The issue you have has its roots in how anchors ^ and $ work.
^ matches at the beginning (right before the first character, or \n in our case), and $ matches at the end of string (at \n). When you press Return, your string looks like \n. Exactly a match!
So, in your case [0-9]* can match an empty string due to the * quantifier (0 or more occurrences of the preceding pattern).
So, you can avoid matching an empty string with a negative look-ahead:
#"^(?!\n$)[0-9]*$"
It will not match an empty string with just a newline symbol in it. See this demo.

Regex for numbers with optional decimal value, fixed to two positions?

I need to know if a string is in the following format:
Any number of integers followed by:
an optional group of:
a decimal followed by two digits (required if a decimal is provided)
This allows any number of digits, and I thought it was in the proper format to allow an optional group that consists of a period followed by two digits, but for some reason this doesn't allow the decimal. Perhaps the decimal isn't escaped appropriately?
#"^[0-9]+(\\.[0-9][0-9])?$"
I tried #"^[0-9]+(\.[0-9][0-9])?$" but Xcode throws a compile-time warning: Unknown escape sequence \..
I suggest using ^[0-9]+(?:\\.[0-9]{2})?$ regex (in Objective C, we need to escape regex backslash).
^ - String start
[0-9]+ - Any number of digits
(?:\\.[0-9]{2})? - Optional group:
\\. - A literal dot
[0-9]{2} - Exactly two digits
$ - String end
Here is a sample code you can use (it will report a match in this case):
NSString *pattern = #"^[0-9]+(?:\\.[0-9]{2})?$";
NSString *string = #"12345.20";
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
NSRange textRange = NSMakeRange(0, string.length);
NSRange matchRange = [regex rangeOfFirstMatchInString:string options:NSMatchingReportProgress range:textRange];
// Did we find a matching range
if (matchRange.location != NSNotFound)
NSLog (#"YES! It is matched!");
else
NSLog (#"NO MATCH!");

Match the Second Time a Word is Found In Regex

I'm pretty new to Regex and I'm just trying to get my head around it. The string I am trying to search through is this:
100 ON 12C 12,41C High Cool OK 0
101 OFF 32C 04,93C Low Dry OK 1
102 ON 07C 08,27C High Dry OK 0
What I am trying to do is work out the part to find the part 32C from the string. If possible, would the code be able to be changed a little each time in order to find the Nth occurrence of the word in the String. If it makes any difference I am going to be using this code in an iPhone application and thus Objective-C.
Your example is line-oriented and of equal weight (at the same time) biased towards the beginning of the line in the string.
If your engine flavor does grouping, you should be able to specify an occurance quantifier that will get you a single exact answer, without the need to do arrays and such.
In both cases the answer is in capture buffer 1.
examples:
$occurance = "2";
---------
/(?:[^\n]*?(\d+C)[^\n]*.*?){$occurance}/s
---------
or
---------
/(?:^.*?(\d+C)[\S\s]*?){$occurance}/m
expanded:
/
(?:
[^\n]*?
( \d+C )
[^\n]* .*?
){2}
/xs
/
(?:
^ .*?
( \d+C )
[\S\s]*?
){2}
/xm
You could try something like the following. You will have to replace regex_pattern with your regular expression pattern. In your case, regex_pattern should be something like #"\\s\\d\\dC" (a whitespace character (\\s) followed by a digit (\\d) followed by a digit (\\d) followed an upper-case letter C.
You may also wish to remove the NSRegularExpressionCaseInsensitive option if you can be sure that the letter C will never be lower case.
NSError *error = nil;
NSString *regex_pattern = #"\\s\\d\\dC";
NSRegularExpression *regex =
[NSRegularExpression regularExpressionWithPattern:regex_pattern
options:(NSRegularExpressionCaseInsensitive |
NSRegularExpressionDotMatchesLineSeparators)
error:&error];
NSArray *arrayOfMatches = [regex matchesInString:myString
options:0
range:NSMakeRange(0, [myString length])];
// arrayOfMatches now contains an array of NSRanges;
// now, find and extract the 2nd match as an integer:
if ([arrayOfMatches count] >= 2) // be sure that there are at least 2 elements in the array
{
NSRange rangeOfSecondMatch = [arrayOfMatches objectAtIndex:1]; // remember that the array indices start at 0, not 1
NSString *secondMatchAsString = [myString substringWithRange:
NSMakeRange(rangeOfSecondMatch.location + 1, // + 1 to skip over the initial space
rangeOfSecondMatch.length - 2)] // - 2 because we ignore both the initial space and the final "C"
NSLog(#"secondMatchAsString = %#", secondMatchAsString);
int temperature = [secondMatchAsString intValue]; // should be 32 for your sample data
NSLog(#"temperature = %d", temperature);
}