NSCharacterSet - append another character set - objective-c

I would like to create a character set that includes all of its own characters, as well as those from another character set. Append in other words.
I thought there'd be an obvious way, but after control-space completion in the IDE, and then poking around the docs, I couldn't fine anything.
I can see how to append all the characters from a string. But I need to append the characters from another set. I guess I could to-string the second set, if there's a to-string method.
How do I do this?

You are probably seaching for this method in NSMutableCharacterSet :
- (void)formUnionWithCharacterSet:(NSCharacterSet *)otherSet
From Doc:
Modifies the receiver so it contains all characters that exist in
either the receiver or otherSet.

For Swift 3:
let fullCharset = aCharset.union(anotherCharset)

Related

Regular expression to extract a number of steps

I have a localized string that looks something like this in English:
"
5 Mile(s)
5,252 Step(s)
"
My app is localized both in left-to-right and right-to-left languages so I don't want to make assumptions either about the ordering of the step(s) or about the formatting of the number (e.g. 5,252 can be 5.252 depending on user locale). So I need to account for possibilities that can include things like
Step(s) 5.252
as well as what's above.
A few other caveats
All I know is that if the Step(s) line is in there, it will be on its own line (hence in my regex I require \n at each end of the string)
No guarantee that the Mile(s) information will be in the string at all, let alone whether it will be before or after Step(s)
Here's my attempt at pattern extraction:
NSString *patternString = [NSString stringWithFormat:#"\\n(([0-9,\\.]*)\s*%#|%#\s*([0-9,\\.]*))\\n",
NSLocalizedString(#"Step(s)",nil), NSLocalizedString(#"Step(s)",nil)];
There appear to be two problems with this:
XCode is indicating Unknown escape sequence '\s' for the second \s in the pattern string above
No matches are being found even for strings like the following:
0.2 Mile(s)
1,482 Step(s)
Ideally I would extract the 1,482 out of this string in a way that is localization friendly. How should I modify my regex?
as far as the regex, perhaps this approach might work - it simply matches (with named groups) each couplet of numbers in sequence, with the assumption the first is miles and the second is steps. Decimals in the . or , form are optional:
(?<miles>\d+(?:[.,]\d+)?).*?(?<steps>\d+(?:[.,]\d+)?)
(and i think it should be \\s) - i'm not an ios guy, but if you can use a regex literal it would be way more readable.
regular expression demo
First I'd like to ask - Why is Mile(s) mentioned in the question at all?
And now to my two bits - you could simply use a positive look-ahead:
^(?=.*Step\(s\))[^\d]*(\d+(?:[.,]\d+)?)
It makes sure the expected word is present on the line, and then captures the number on it, allowing for localized, optional, decimal separator and decimals. This way it doesn't matter if the numer is before, or after, the "word".
It doesn't take localization of the "word" into account, but that you seem to have handled by yourself ;)
See it here at regex101.
Your regex is close, although in Obj-C you need to double-escape the \s and (s):
^(([0-9,.]*)\\s*%#|%#\\s*([0-9,.]*))$
In your NSLocalizedString you likely also need to escape the parentheses enclosing (s):
NSString *patternString = [NSString stringWithFormat:#"^(([\\d,.]+)\\s%#|%#\\s([\\d,.]+))$",
NSLocalizedString(#"Step\\(s\\)",nil), NSLocalizedString(#"Step\\(s\\)",nil)];
If you don't escape (s) then the regex engine is probably going to interpret it as a capture group.
Looking at NSLog you can see what the pattern actually reads like:
NSLog(#"patternString: %#", patternString);
Output:
patternString: ^(([\d,.]+)\sStep\(s\)|Step\(s\)\s([\d,.]+))$
Since you mentioned the Mile(s) part may not be in the string at all I'm assuming it isn't relevant to the regular expression. As I understand from the question, you just need to capture the number of steps and nothing else. On this basis, here's a modified version of your existing regex:
NSString *patternString =
[NSString stringWithFormat:#"^(?:([0-9,.]*)\\s*%#|%#\\s*([0-9,.]*))$",
NSLocalizedString(#"Step\\(s\\)",nil), NSLocalizedString(#"Step\\(s\\)",nil)];
Demo:
https://www.regex101.com/r/Q6ff1b/1
This is based on the following tips/modifications:
Use the m (= UREGEX_MULTILINE) flag option when creating the regex to specify that ^ and $ match the start and end of each line. This is more sophisticated than using \n as it will also handle the start and end of the string where this might not be present. See here.
Always use a double backslash (\\) for regex escaping - otherwise NSString will interpret the single backslash to be escaping the next character and convert it before it gets to the regex.
Literal parentheses need to be escaped - e.g. Step\\(s\\) instead of Step(s).
Characters within a character class (i.e. anything within the [] square brackets) don't need to be escaped - so it would be . rather than \\. - the latter.
If you are using (x|y|...) as a choice and don't need it to be a capturing group, use ?: after the first parenthesis to ensure it doesn't get captured - i.e. (?:x|y|...).

Regex positive lookbehind

Let me apologize first. I've been fighting this SO editor for an hour. Sorry for the lousy formatting.
If I have a regex that matches a given input, then I put that regex into the positive look-behind wrapper, won't it still match the input it matched before?
For example, this input :
(NSString*)
will register a match with this regex:
\(\w*\*\)
I have confirmed this on gskinner.com. When I put that regex into the look-behind wrapper like so
(?<=\(\w*\*\))....
with this as the input:
(NSString*)help
I do not receive the word help as a return.
This leads me to think I just plainly don't understand the look-behind concept. I watched a tutorial on this concept, but I am at a loss as to why this won't work. If I want to match:
(NSString*)
and return the next word, how can I go about that?
You have a space as the last character of the look behind, but your input has no space before "help". Also, there is no colon character before the input text, yet your look behind requires one.
Remove the space and the colon:
(?<=\(\w*\*\))\w+
Note that many regex engines disallow variable length look behinds, so a work around is to limit the.number of characters in the word to some large number, eg 99:
(?<=\(\w{1,99}\*\))\w+

Filtering out substring from NSString . . .maybe using regex

Here is my problem:
I am trying to filter out html tags from an NSString object.
Most fixes for this simply remove everything falling between a < and a >, as well as those characters themselves. I am trying to figure out a way to remove the "< . . . >" substring ONLY if it does not contain white space or newline characters.
The way i was thikning about doing it looks something like this
while ([source rangeOfString#"someRegEx" options:NSRegularExpressionSearch].location != NSNotFound) {
//find the range of the substring
//check for newlines/whitespace characters
//replace occurrences of the string with "" if it doesn't have them
}
Firstly, does this seem like a good approach? Secondly, I'm having a lot of problems with figuring out what that regex would look like... does anyone have any ideas what it might look like?
This seems like a fine approach, provided the tags you're looking for really never contain whitespace, as m.buettner points out. The regex would look something like this:
<[^\s]*?>
The [^\s] is a negated character class which matches anything but whitespace characters. The ? makes the * lazy instead of greedy. So this regex in English means "Match a '<', then the smallest possible number of non-whitespace characters, then a '>'."
This is a helpful page.
Maybe you should consider employing an NSXMLParser, described here.
You get quite a rich set of delegate methods to extract whatever you like from the string.

Code for converting long string to pass in URL

I am trying to take a string like "Hello my name is Nick" and transform it to "Hello+my+name+is+Nick" to be passed through a URL. This would be easily done by replacing all the spaces with a + char however I also need to replace all special characters (. , ! &) with their ASCII values. I have searched the net but cannot find anything. I wonder if anyone knows of existing code to do this as its a fairly common task?
I think you're looking for this: HttpUtility.UrlEncode Method (String)
Handles non-URL compliant characters and spaces.

RegexKitLite Not Matching NSString Correctly

Alright, I'm trying to write some code that removes words that contain an apostrophe from an NSString. To do this, I've decided to use regular expressions, and I wrote one, that I tested using this website: http://rubular.com/r/YTV90BcgoQ
Here, the expression is: \S*'+\S
As shown on the website, the words containing an apostrophe are matched. But for some reason, in the application I'm writing, using this code:
sourceString = [sourceString stringByReplacingOccurrencesOfRegex:#"\S*'+\S" withString:#""];
Doesn't return any positive result. By NSLogging the 'sourceString', I notice that words like 'Don't' and 'Doesn't' are still present in the output.
It doesn't seem like my expression is the problem, but maybe RegexKitLite doesn't accept certain types of expressions? If someone knows what's going on here, please enlighten me !
Literal NSStrings use \ as an escape character so that you can put things like newlines \n into them. Regexes also use backslashes as an escape character for character classes like \S. When your literal string gets run through the compiler, the backslashes are treated as escape characters, and don't make it to the regex pattern.
Therefore, you need to escape the backslashes themselves in your literal NSString, in order to end up with backslashes in the string that is used as the pattern: #"\\S*'+\\S".
You should have seen a compiler warning about "Unknown escape sequence" -- don't ignore those warnings!