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);
}
Related
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.
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!");
How I can split a string into equal parts and not a character, ie, a string that is 20 characters divided into 5 strings with 2 characters each no matter what kind of character is?
don't work to me [NSString componentsSeparatedByString]: because the characters change randomly.
i'm using objetive-c on xcode 5
This is just an example of what you're probably looking to do. This method assumes the length of the string is evenly divisible by the intended substring length, so having a test string with 20 characters and a substring length of 2, will produce an array with 10 substrings with 2 characters in each. If the test string is 21 characters the 21st char will be ignored. Once again, this is not THE way to do exactly what you want to do (which still isn't totally clear), but it is merely a demonstration of something similar to what you may want to be doing:
// create our test substring (20 chars long)
NSString *testString = #"abcdefghijklmnopqrstu";
// our starting point will begin at 0
NSInteger startingPoint = 0;
// each substring will be 2 characters long
NSInteger substringLength = 2;
// create our empty mutable array
NSMutableArray *substringArray = [NSMutableArray array];
// loop through the array as many times as the substring length fits into the test
// string
for (NSInteger i = 0; i < testString.length / substringLength; i++) {
// get the substring of the test string starting at the starting point, with the intended substring length
NSString *substring = [testString substringWithRange:NSMakeRange(startingPoint, substringLength)];
// add it to the array
[substringArray addObject:substring];
// increment the starting point by the amount of the substring length, so next iteration we
// will start after the last character we left off at
startingPoint += substringLength;
}
The above produced this:
2014-08-23 15:33:41.662 NewTesting[49723:60b] (
ab,
cd,
ef,
gh,
ij,
kl,
mn,
op,
qr,
st )
I'm writing a Mac app that goes through an NSString, and adds all its word to an NSArray (by separating them based on whitespace). Now, I've got the whole system down, but I'm still having one little problem: names (first + last), are added as two different words, and that's bothersome to me.
I thought of a couple solutions to fix this. My best idea was to, before actually adding the words to the array, join two words in a row that are capitalized. Then, through an if statement, determine if a word has two capitals in it, and then split the word and add it as one word. However, I can't find a way to find 2 words in a row with capitals.
Should I be using RegexKitLite (which I'm not familiar with), for example, to find two capitalized words in a row? I've seen this question: Regexp to pull capitalized words not at the beginning of sentence and two adjacent words
which seems somehow related, but due to my lack of understand of regular expressions, I don't really know if this is exactly what I need.
I've also seen this: Separating NSString into NSArray, but allowing quotes to group words
which is also similar, yet not exactly adapted to my needs.
So, to conclude, does anyone know how to either join capitalized words in an NSString, or even better, how to find two capitalized words in a row in an NSString ?
If you're targeting iOS 4.0 or greater OR OS 10.7 you can use NSRegularExpression
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:#"[A-Z]\\w*\\s[A-Z]\\w*"
options:nil
error:&error];
NSString *inputString = #"One two Three Four five six Seven Eight";
NSArray *stringsWithTwoCapitalizedWordsInARow = [regex
matchesInString:inputString
options:0
range:NSMakeRange(0, [string length])];
You'll get something like this
["Three Four", "Seven Eigth"]
You could just do a second pass on the resulting array after it has been loaded to append entries together that need to be joined.
Names are notoriously difficult to match with regular expressions alone, as it is not unheard of for names (first or last) to contain spaces themselves.
NSMutableArray* words = ...;
NSMutableArray* joinedWords = [NSMutableArray array];
for (int i=0; i < [words length]; i++)
{
NSString* currentLine = [words objectAtIndex:i];
bool capitalized = false;
bool capitalizedNext = false;
capitalized = isCap(currentLine); // Up to your discretion here
NSString* nextLine = nil;
// for the last entry
if (i+1 < [words length])
{
nextLine = [words objectAtIndex:i+1];
capitalizedNext = isCap(nextLine);
}
// Check if first letter is uppercase
if (capitalized == true && capitalizedNext == true)
{
[words replaceObjectAtIndex:i withObject:[NSString stringWithFormat:#"%# %#", currentLine, nextLine];
[words removeObjectAtIndex:i+1];
// Run test again on new version of the line
i--;
}
else
{
[joinedWords addObject:currentLine];
}
}
[A-Z][A-Za-z]* [A-Z][A-Za-z]*|[\S]*
http://rubular.com/r/DrOabOAfBr
I've written a regular expression for you. This regex will try to match a name first, then fall back to a word, so your job is as simple as feeding this into NSRegularExpression, and take all the matches as your words, or names joined.
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 .+