I have a Regular Expression in Objective-C and I need to know how to get a certain variable...
I want to find a string that has the letter "a" somewhere in it followed by any number (including zero) of B's, C's, and D's after it and at the first non-B,C,D I want to close my search statement. Then I want to replace the A with an F and add an F to the end of my search-string.
For example: "ZYXABCBBDBCBDEJKS" would search and return: "ZYXABCBBDBCBDEJKS" ... so the string I am now working with is "ABCBBDBCBDE", I want this string to turn into this string "FBCBBDBCBDEF" and then be put back into the original string... so the final returned string will be "ZYXFBCBBDBCBDEFJKS"
I'm new to RegEx but I gave it a shot with the below objective-c code and it didn't work... I think this is because my variables on the second line of code (at the "withTemplate" part) are wrong... I shouldn't use "$2" or "$1" should I?
code:
regex = [NSRegularExpression regularExpressionWithPattern:#"A(B|C|D)*([^B|C|D])"
options:0
error:nil];
modifiedString = [regex stringByReplacingMatchesInString:myString
options:0
range:NSMakeRange(0, [htmlstring length])
withTemplate:#"F$1$2F"];
In your regex - (B|C|D)* will only capture the last matched character out of (B|C|D), since * is out of the captured group. Also, in a character class, you don't need to use a pipe to alternate, as you did in 3rd part. So, either you use character class, or you use pipe to alternate in groups. And in this particular case, I would suggest to use character class in both place.
So, you can try changing your regex to:
"A([BCD]*)([^BCD])"
Related
Is a regex of the following form legit in Obj C?
"<(img|a|div).*?>.*?</$1>"
I know it's valid in JS with a \1 instead of $1, but I'm having little luck in Obj C.
NSRegularExpression uses ICU Regular Expressions which uses \n syntax for back references where n is the nth capture group.
<(img|a|div).*?>.*?</\\1>
Yes, I do believe you can work with capture groups. I had to work with them a bit a little while ago and I have an example in:
-(NSString *) extractMediaLink:(NSString *)link withRegex:(NSString *)regex{
NSString * utf8Link = [link stringByRemovingPercentEncoding];
NSError * regexError = nil;
NSRegularExpression * regexParser = [NSRegularExpression regularExpressionWithPattern:regex
options:NSRegularExpressionCaseInsensitive|NSRegularExpressionUseUnixLineSeparators
error:®exError];
NSTextCheckingResult * regexResults = [regexParser firstMatchInString:utf8Link
options:0
range:NSMakeRange(0, [utf8Link length])];
NSString * matchedResults = [utf8Link substringWithRange:[regexResults rangeAtIndex:1]]; // the second capture group will always have the ID
return matchedResults.length ? matchedResults : #"";
}
When you use an instance of NSRegularExpression to generate an NSTextCheckingResult, the NSTextCheckingResult has a property of numberOfRanges which is documented with:
A result must have at least one range, but may optionally have more (for example, to represent regular expression capture groups).
In my example above (Note: I happen to be parsing HTML, but using an addition pod that traverses HTML by XPath queries, TFHpple -- a lifesaver if you absolutely have to parse HTML), I use the -[NSRegularExpression firstMatchInString:options:range:] to check for the first instance of the tag that matches my regex pattern. From that NSTextCheckingResult I pull out the proper index of the capture group I'm interested in (in this case, [regexResults rangeAtIndex:1])
But, getting to this point was a huge pain in the ass. But to make sure you're getting the right expressions I would highly recommend using Regex101 with the Python setting, and then passing the refined regex into Patterns (Mac App Store)
If you want the full look, I have a fairly detailed project here, but keep in mind it's still a WIP.
regular expression need to accept +,-,& need to accept before # in email validation
([\w-\.]+)#((?:[\w]+\.)+)([a-zA-Z]{2,4}) in this regular expression its not accepting.
can any one provide me proper regular expression.
Example:
demo+wifi-mail&name#gmail.com
use this one it'l helps you.
([\\w-\\.\\+\\-\\&}]+)#((?:[\\w]+\\.)+)([a-zA-Z]{2,4})
NSString *phone=#"demo+wifi-mail&name#gmail.com";
NSString *pNRegex = #"([\\w-\\.\\+\\-\\&}]+)#((?:[\\w]+\\.)+)([a-zA-Z]{2,4})";
NSPredicate *PNTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", pNRegex];
BOOL check=[PNTest evaluateWithObject:phone ];
NSLog(#"%i",check);----> 1
This [\w\.] is a character class (I removed the - for now). Every character that is within the square brackets is matched by this class. So, your class is matching all letters, digits and underscores (that is done by the \w part) and dots.
If you want additional characters, just add them to the character class, e.g. [\w.+&-].
Be careful with the - character, it has a special meaning in a character class, either escape it or put it at the start or the end.
But be aware, your regex is still not matching all valid email addresses, see the links in the comments.
Single characters (without special meaning) or predefined classes written in a class doesn't make sense, [\w] is exactly the same than \w.
([\w-.+-\&}]+)#((?:[\w]+.)+)([a-zA-Z]{2,4}) Now it will work!
Backgroud:
I have a response like so (please note the new lines):
HTTP/1.1 200 OK
CACHE-CONTROL: max-age = 180
EXT:
LOCATION: http://172.16.16.16:80/upnp.jsp
SERVER: Linux/2.6.32.24 UPNP/1.0 ZD3025/9.5.1.0
ST: upnp:rootdevice
USN: uuid:6e4bb543-fff6-4384-a4be-::upnp:rootdevice
I would like to match the Server line which is:
Linux/2.6.32.24 UPNP/1.0 ZD3025/9.5.1.0
Implementation:
I don't care about any character in the above given response EXCEPT for the characters Linux, UPNP and ZD (in that order).
So I am using .* to match any number of characters, numbers, special chars.
-(void) regexCompareForUPnP:(NSString *) string {
NSError * err = nil;
//Building expression
NSString *expression = #"^.*Linux.*UPNP.*ZD.*$";
NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:expression options:0 error:&err];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:string
options:0
range:NSMakeRange(0, [string length])];
NSLog(#"Matches found: %d", numberOfMatches);
}
So far, Matches found: 0.
Question:
So, in short does this:
NSString *expression = #"^.*Linux.*UPNP.*ZD.*$";
Match this:
Linux/2.6.32.24 UPNP/1.0 ZD3025/9.5.1.0
EDIT:
Thank you omz that worked perfectly.
Now I am trying to match the upnp.jsp (in the LOCATION line) alongwith what I was trying to match before. So I tried this:
NSString *expression = #"^.*upnp.jsp\n.*Linux.*UPNP.ZD.$";
That does not work. Appreciate your help..
I'm not familiar with this regex library. Based on what you're trying to match, however, it may be to do with newlines between OS's and individual programs.
Try this: *expression = #"upnp.jsp\r?\n[^\n]*?Linux[^\n]*?UPNP[^\n]*?ZD"
A few other changes made from what you're trying as well;
I've replaced .* with [^\n]*? for two reasons:
I'm not sure how this library deals with .*, but using that is typically inefficient in comparison to something more speicific such as looking for a non-greedy set of characters that aren't a new line. The difference between .* and .*? depends on the regex engine. In most regex engines I work with at least, .* is by default greedy; i.e. it will capture as much data as it can while still having the expression find a match. Using the non-greedy version, .*?, means that the regex will capture only as much as it needs to to satisfy the whole expression. This is particularly evident in an example I'll expand on at the end.
I removed the surrounding ^$ because when they are appended and prepended with .* they only work towards increasing processing time (unless you were using matching groups, which you aren't). If you were doing ^(.*)upnp or ^(.*upnp) and then using the contents of the matched group, there could be purpose in having the initial ^.*.
As for greedy/non-greedy, the difference becomes evident when trying to match data between a set of double quotes ". For the sake of simplicity, I won't deal with having escaped double quotes in the middle of a string you also want to capture.
Given the string: I said, "Hi." She responded with, "Hello!"
Using the greedy regex "(.*)", the matched group would be Hi." She responded with, "Hello!
Using the non-greedy regex "(.*?)", the matched group would be Hi.
I have a long string. I'd like to take this long string, search for any occurrences of words that appear between quotes (i.e., "string"), and insert a string before the word (i.e., "x"), and a string after the word (i.e., "y").
Any solutions would be most appreciated! Thanks!
I see that I could use the following to grab the text between the quotes:
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"([\"])
(?:\\\\\\1|.)*?\\1" options:0 error:&error];
NSRange range = [regex rangeOfFirstMatchInString:myString options:0 range:NSRangeMake(0,
[myString length]];
However, now I need to replace the text that is inside the quotations, inserting the html tags "bold" before and "/bold" after. Is there anyway for me to do this? Also, if there are multiple occurrences of quoted text in a given string, how would I use the above code to cycle through the string to get modify each piece of quoted text one-by-one?
I came across this post ([click here]]1 but I'm not quite sure how to modify the sample code to achieve the result I want. Any help would be great!
I will refer you to this page: Shortcuts in Objective-C to concatenate NSStrings
The page talks about adding strings together by using two NSMutable strings and adding one to both, which seems to be the preferable of the two it gives. Unfortunately, there is no operation to add two or more strings together (which really sucks).
Try this:
NSString *original=#"The quick 'brown fox' The quick 'brown fox' ";
NSString *target=[original stringByReplacingOccurrencesOfString:#"'brown fox'" withString:#"<b>brown fox</b>"];
How should I handle text formatting in iOS? I'm not talking about Currency or Decimal styles. Since iOS doesn't have setFormat(), it's kind of complicated.
Two examples of the format I want: 123.456.789-10 and 123.456.789/1000-00.
My aim is to format a text field as the user types. Like any normal site does when, for example, you type a phone number. It doesn't comes from a model or anything. The user just needs to type the numbers and when necessary I'll insert the ".","/" or "-".
You can use regular expressions to do formatting, like this:
NSRegularExpression *fmt = [NSRegularExpression
regularExpressionWithPattern:#"(.{1,3})(.{1,3})(.{1,3})(.{1,2})"
options:0
error:NULL];
NSMutableString *str = [NSMutableString stringWithString:#"12345678910"];
[fmt replaceMatchesInString:str
options:0
range:NSMakeRange(0, str.length)
withTemplate:#"$1.$2.$3-$4"];
This transforms the string into 123.456.789-10
In order to apply this formatting dynamically as users type, create NSRegularExpression *fmt upfront, store it in your UITextFieldDelegate, and use it in your textField:shouldChangeCharactersInRange:replacementString: method.
I created my own method a couple days ago for checking for valid temperature input. It was a bit of a pain as well because I had to check for:
-only numbers
-only one decimal point
-if there was a negative sign it had to be at the front
I ended up using [my string characterAtIndex:index]; and checking each character, since i would have no more than 4 characters.
EDIT:
Here is some pseudo code
for (every char in your string)
if(the index of the char % 3 == 2) //every third char, 0,2,5...
the char must be a . or / or -
else
the char must be a number