Trimmed values while parsing XML file [duplicate] - swift

I'm new with iOS developing and i'm looking for a solution to compare two String ignoring the spaces at the beginning or at the ending. For example, "Hello" == "Hello " should return true.
I've serached for a solution but i didn't find nothing in Swift. Thanks

I would recommend you start by trimming whitespace from the String with this Swift code:
stringToTrim.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())

NSString *string1 = #" Hello";
//remove(trim) whitespaces
string1 = [string1 stringByReplacingOccurrencesOfString:#" " withString:#""];
NSString *string2 = #"Hello ";
//remove(trim) whitespaces
string2 = [string1 stringByReplacingOccurrencesOfString:#" " withString:#""]
// compare strings without whitespaces
if ([string1 isEuqalToString:string2]) {
}
So if you want to use it directly -
if ([[yourString1 stringByReplacingOccurrencesOfString:#" " withString:#""] isEuqalToString:[yourString2 stringByReplacingOccurrencesOfString:#" " withString:#""]]) {
// Strings are compared without whitespaces.
}
Above will remove all whitespaces of your string, if you want to remove only leading and trailing whitespaces then there are a couple of post already available, you can create a category of string as mentioned in following stack overflow post - How to remove whitespace from right end of NSString?
#implementation NSString (TrimmingAdditions)
- (NSString *)stringByTrimmingLeadingCharactersInSet:(NSCharacterSet *)characterSet {
NSUInteger location = 0;
NSUInteger length = [self length];
unichar charBuffer[length];
[self getCharacters:charBuffer];
for (location; location < length; location++) {
if (![characterSet characterIsMember:charBuffer[location]]) {
break;
}
}
return [self substringWithRange:NSMakeRange(location, length - location)];
}
- (NSString *)stringByTrimmingTrailingCharactersInSet:(NSCharacterSet *)characterSet {
NSUInteger location = 0;
NSUInteger length = [self length];
unichar charBuffer[length];
[self getCharacters:charBuffer];
for (length; length > 0; length--) {
if (![characterSet characterIsMember:charBuffer[length - 1]]) {
break;
}
}
return [self substringWithRange:NSMakeRange(location, length - location)];
}
#end
Now once you have the methods available, you can call these on your strings to trim leading and trailing spaces like -
// trim leading chars
yourString1 = [yourString1 stringByTrimmingLeadingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
// trim trainling chars
yourString1 = [yourString1 stringByTrimmingTrailingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
// trim leading chars
yourString2 = [yourString2 stringByTrimmingLeadingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
// trim trainling chars
yourString2 = [yourString2 stringByTrimmingTrailingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
// compare strings
if([yourString1 isEqualToString: yourString2]) {
}

For Swift 3.0+
Use .trimmingCharacters(in: .whitespaces) before comparison or .trimmingCharacters(in: .whitespacesAndNewlines)

In Swift 4
Use it on any String type variable.
extension String {
func trimWhiteSpaces() -> String {
let whiteSpaceSet = NSCharacterSet.whitespaces
return self.trimmingCharacters(in: whiteSpaceSet)
}
}
And Call it like this
yourString.trimWhiteSpaces()

Related

Replacing instances of a character with two different characters in Objective-C

I have a huge amount of NSStrings in a database that get passed to a view controller in an iOS app. They are formatted as "This is a message with $specially formatted$ content".
However, I need to change the '$' at the start of the special formatting with a '[' and the '$' at the end with ']'. I have a feeling I can use an NSScanner but so far all of my attempts have produced wackily concatenated strings!
Is there a simple way to recognise a substring encapsulated by '$' and swap them out with start/end characters? Please note that a lot of the NSStrings have multiple '$' substrings.
Thanks!
You can use regular expressions:
NSMutableString *str = [#"Hello $World$, foo $bar$." mutableCopy];
NSRegularExpression *regex;
regex = [NSRegularExpression regularExpressionWithPattern:#"\\$([^$]*)\\$"
options:0
error:NULL];
[regex replaceMatchesInString:str
options:0
range:NSMakeRange(0, [str length])
withTemplate:#"[$1]"];
NSLog(#"%#", str);
// Output:
// Hello [World], foo [bar].
The pattern #"\\$([^$]*)\\$" searches for
$<zero_or_more_characters_which_are_not_a_dollarsign>$
and all occurrences are then replaced by [...]. The pattern contains so many backslashes because the $ must be escaped in the regular expression pattern.
There is also stringByReplacingMatchesInString if you want to create a new string instead of modifying the original string.
I think replaceOccurrencesOfString: won't work cause you have start$ and end$.
But if you seperate the Strings with [string componentsSeperatedByString:#"$"] you get an Array of substrings, so every second string is your "$specially formatted$"-string
This should work!
NSString *str = #"This is a message with $specially formatted$ content";
NSString *original = #"$";
NSString *replacement1 = #"[";
NSString *replacement2 = #"]";
BOOL start = YES;
NSRange rOriginal = [str rangeOfString: original];
while (NSNotFound != rOriginal.location) {
str = [str stringByReplacingCharactersInRange: rOriginal withString:(start?replacement1:replacement2)];
start = !start;
rOriginal = [str rangeOfString: original];
}
NSLog(#"%#", str);
Enjoy Programming!
// string = #"This is a $special markup$ sentence."
NSArray *components = [string componentsSeparatedByString:#"$"];
// sanity checks
if (components.count < 2) return; // maybe no $ characters found
if (components.count % 2) return; // not an even number of $s
NSMutableString *out = [NSMutableString string];
for (int i=0; i< components.count; i++) {
[out appendString:components[i]];
[out appendString: (i % 2) ? #"]" : #"[" ];
}
// out = #"This is a [special markup] sentence."
Try this one
NSMutableString *string=[[NSMutableString alloc]initWithString:#"This is a message with $specially formatted$ content. This is a message with $specially formatted$ content"];
NSMutableString *string=[[NSMutableString alloc]initWithString:#"This is a message with $specially formatted$ content. This is a message with $specially formatted$ content"];
BOOL open=YES;
for (NSUInteger i=0; i<[string length];i++) {
if ([string characterAtIndex:i]=='$') {
if (open) {
[string replaceCharactersInRange:NSMakeRange(i, 1) withString:#"["];
open=!open;
}
else{
[string replaceCharactersInRange:NSMakeRange(i, 1) withString:#"]"];
open=!open;
}
}
}
NSLog(#"-->%#",string);
Output:
-->This is a message with [specially formatted] content. This is a message with [specially formatted] content

NSString strip regular \ escape characters how?

I need an efficient piece of code that strips escape characters. This is regular escapes not HTML escape characters.
Example: "\"", "\\\\", "\", "\\"
I want a general algorithm to strip any kind of escape sequences.
Could use any utility like regular expression.
(NSString*) unescape:(NSString*) string {
....
}
This is the answer I wrote:
-(NSString*) unescape:(NSString*) string
{
for(int i = 0; i < string.length; i++) {
char a = [string characterAtIndex:i];
if([string characterAtIndex:i] == '\\' ) {
string = [string stringByReplacingCharactersInRange:NSMakeRange(i,1) withString:#""];
}
}
return string;
}
Try to use below code for HTML escape
(NSString*) unescape:(NSString*) string
{
return [string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
}
for regular Escape
(NSString*) unescape:(NSString*) string
{
return [string stringByReplacingOccurrencesOfString:#"\\\"" withString:#"\""];
}
The best method that you should use is:
- (NSString *)stringByTrimmingCharactersInSet:(NSCharacterSet *)set
You would call it using:
string = [string stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
If you want to use regex, you can try with regex pattern \\[bntr\\\\"]. Or use any required regex pattern here.
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:
#"\\[bntr\\\\"]" options:0 error:nil];
[regex replaceMatchesInString:str options:0 range:NSMakeRange(0, [str length]) withTemplate:#""];
I apoligize for my answer...
NSString *_string = #"\\\\ dfsdg \\ tr\\\\t \\\\\\tw\\\\\\\\w\\ t\\ \\\\ \\ \\\\\\ rret\\ \\\\ \\\\\\\\";
NSLog(#"%#", [_string stringByReplacingOccurrencesOfString:#"\\" withString:#""]);
result is:
dfsdg trt tww t rret
If its URL Encoded, you are probably looking for:
stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding
Hope this helps:
-(NSString *)unescape:(NSString *)string
{
if ([string rangeOfString:#"\\"].location != NSNotFound)
{
[string stringByReplacingCharactersInRange:#"\\" withString:#"\\"];
}
else if ([string rangeOfString:#"\\\\"].location != NSNotFound)
{
[string stringByReplacingCharactersInRange:#"\\\\" withString:#"\\"];
}
else if ([string rangeOfString:#"\\\\"].location != NSNotFound)
{
[string stringByReplacingCharactersInRange:#"\\\\" withString:#"\\"];
}
}

Objective-C: Find numbers in string

I have a string that contains words as well as a number. How can I extract that number from the string?
NSString *str = #"This is my string. #1234";
I would like to be able to strip out 1234 as an int. The string will have different numbers and words each time I search it.
Ideas?
Here's an NSScanner based solution:
// Input
NSString *originalString = #"This is my string. #1234";
// Intermediate
NSString *numberString;
NSScanner *scanner = [NSScanner scannerWithString:originalString];
NSCharacterSet *numbers = [NSCharacterSet characterSetWithCharactersInString:#"0123456789"];
// Throw away characters before the first number.
[scanner scanUpToCharactersFromSet:numbers intoString:NULL];
// Collect numbers.
[scanner scanCharactersFromSet:numbers intoString:&numberString];
// Result.
int number = [numberString integerValue];
(Some of the many) assumptions made here:
Number digits are 0-9, no sign, no decimal point, no thousand separators, etc. You could add sign characters to the NSCharacterSet if needed.
There are no digits elsewhere in the string, or if there are they are after the number you want to extract.
The number won't overflow int.
Alternatively you could scan direct to the int:
[scanner scanUpToCharactersFromSet:numbers intoString:NULL];
int number;
[scanner scanInt:&number];
If the # marks the start of the number in the string, you could find it by means of:
[scanner scanUpToString:#"#" intoString:NULL];
[scanner setScanLocation:[scanner scanLocation] + 1];
// Now scan for int as before.
Self contained solution:
+ (NSString *)extractNumberFromText:(NSString *)text
{
NSCharacterSet *nonDigitCharacterSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
return [[text componentsSeparatedByCharactersInSet:nonDigitCharacterSet] componentsJoinedByString:#""];
}
Handles the following cases:
#"1234" → #"1234"
#"001234" → #"001234"
#"leading text get removed 001234" → #"001234"
#"001234 trailing text gets removed" → #"001234"
#"a0b0c1d2e3f4" → #"001234"
Hope this helps!
You could use the NSRegularExpression class, available since iOS SDK 4.
Bellow a simple code to extract integer numbers ("\d+" regex pattern) :
- (NSArray*) getIntNumbersFromString: (NSString*) string {
NSMutableArray* numberArray = [NSMutableArray new];
NSString* regexPattern = #"\\d+";
NSRegularExpression* regex = [[NSRegularExpression alloc] initWithPattern:regexPattern options:0 error:nil];
NSArray* matches = [regex matchesInString:string options:0 range:NSMakeRange(0, string.length)];
for( NSTextCheckingResult* match in matches) {
NSString* strNumber = [string substringWithRange:match.range];
[numberArray addObject:[NSNumber numberWithInt:strNumber.intValue]];
}
return numberArray;
}
Try this answer from Stack Overflow for a nice piece of C code that will do the trick:
for (int i=0; i<[str length]; i++) {
if (isdigit([str characterAtIndex:i])) {
[strippedString appendFormat:#"%c",[str characterAtIndex:i]];
}
}
By far the best solution! I think regexp would be better, but i kind of sux at it ;-) this filters ALL numbers and concats them together, making a new string. If you want to split multiple numbers change it a bit. And remember that when you use this inside a big loop it costs performance!
NSString *str= #"bla bla bla #123 bla bla 789";
NSMutableString *newStr = [[NSMutableString alloc] init];;
int j = [str length];
for (int i=0; i<j; i++) {
if ([str characterAtIndex:i] >=48 && [str characterAtIndex:i] <=59) {
[newStr appendFormat:#"%c",[str characterAtIndex:i]];
}
}
NSLog(#"%# as int:%i", newStr, [newStr intValue]);
Swift extension for getting number from string
extension NSString {
func getNumFromString() -> String? {
var numberString: NSString?
let thisScanner = NSScanner(string: self as String)
let numbers = NSCharacterSet(charactersInString: "0123456789")
thisScanner.scanUpToCharactersFromSet(numbers, intoString: nil)
thisScanner.scanCharactersFromSet(numbers, intoString: &numberString)
return numberString as? String;
}
}
NSPredicate is the Cocoa class for parsing string using ICU regular expression.

How do you remove extra empty space in NSString?

is there a simple way to remove the extra spaces in a string? ie like...
NSString *str = #"this string has extra empty spaces";
result should be:
NSString *str = #"this string has extra empty spaces";
Thanks!
replace all double space with a single space until there are no more double spaces in your string.
- (NSString *)stripDoubleSpaceFrom:(NSString *)str {
while ([str rangeOfString:#" "].location != NSNotFound) {
str = [str stringByReplacingOccurrencesOfString:#" " withString:#" "];
}
return str;
}

Replace multiple characters in a string in Objective-C?

In PHP I can do this:
$new = str_replace(array('/', ':', '.'), '', $new);
...to replace all instances of the characters / : . with a blank string (to remove them)
Can I do this easily in Objective-C? Or do I have to roll my own?
Currently I am doing multiple calls to stringByReplacingOccurrencesOfString:
strNew = [strNew stringByReplacingOccurrencesOfString:#"/" withString:#""];
strNew = [strNew stringByReplacingOccurrencesOfString:#":" withString:#""];
strNew = [strNew stringByReplacingOccurrencesOfString:#"." withString:#""];
Thanks,
matt
A somewhat inefficient way of doing this:
NSString *s = #"foo/bar:baz.foo";
NSCharacterSet *doNotWant = [NSCharacterSet characterSetWithCharactersInString:#"/:."];
s = [[s componentsSeparatedByCharactersInSet: doNotWant] componentsJoinedByString: #""];
NSLog(#"%#", s); // => foobarbazfoo
Look at NSScanner and -[NSString rangeOfCharacterFromSet: ...] if you want to do this a bit more efficiently.
There are situations where your method is good enough I think matt.. BTW, I think it's better to use
[strNew setString: [strNew stringByReplacingOccurrencesOfString:#":" withString:#""]];
rather than
strNew = [strNew stringByReplacingOccurrencesOfString:#"/" withString:#""];
as I think you're overwriting an NSMutableString pointer with an NSString which might cause a memory leak.
Had to do this recently and wanted to share an efficient method:
(assuming someText is a NSString or text attribute)
NSString* someText = #"1232342jfahadfskdasfkjvas12!";
(this example will strip numbers from a string)
[someText stringByReplacingOccurrencesOfString:#"[^0-9]" withString:#"" options:NSRegularExpressionSearch range:NSMakeRange(0, [someText length])];
Keep in mind that you will need to escape regex literal characters using Obj-c escape character:
(obj-c uses a double backslash to escape special regex literals)
...stringByReplacingOccurrencesOfString:#"[\\\!\\.:\\/]"
What makes this interesting is that NSRegularExpressionSearch option is little used but can lead to some very powerful controls:
You can find a nice iOS regex tutorial here and more on regular expressions at regex101.com
Essentially the same thing as Nicholas posted above, but if you want to remove everything EXCEPT a set of characters (say you want to remove everything that isn't in the set "ABCabc123") then you can do the following:
NSString *s = #"A567B$%C^.123456abcdefg";
NSCharacterSet *doNotWant = [[NSCharacterSet characterSetWithCharactersInString:#"ABCabc123"] invertedSet];
s = [[s componentsSeparatedByCharactersInSet: doNotWant] componentsJoinedByString: #""];
NSLog(#"%#", s); // => ABC123abc
Useful in stripping out symbols and such, if you only want alphanumeric.
+ (NSString*) decodeHtmlUnicodeCharactersToString:(NSString*)str
{
NSMutableString* string = [[NSMutableString alloc] initWithString:str]; // #&39; replace with '
NSString* unicodeStr = nil;
NSString* replaceStr = nil;
int counter = -1;
for(int i = 0; i < [string length]; ++i)
{
unichar char1 = [string characterAtIndex:i];
for (int k = i + 1; k < [string length] - 1; ++k)
{
unichar char2 = [string characterAtIndex:k];
if (char1 == '&' && char2 == '#' )
{
++counter;
unicodeStr = [string substringWithRange:NSMakeRange(i + 2 , 2)]; // read integer value i.e, 39
replaceStr = [string substringWithRange:NSMakeRange (i, 5)]; // #&39;
[string replaceCharactersInRange: [string rangeOfString:replaceStr] withString:[NSString stringWithFormat:#"%c",[unicodeStr intValue]]];
break;
}
}
}
[string autorelease];
if (counter > 1)
return [self decodeHtmlUnicodeCharactersToString:string];
else
return string;
}
Here is an example in Swift 3 using the regularExpression option of replacingOccurances.
Use replacingOccurrences along with a the String.CompareOptions.regularExpression option.
Example (Swift 3):
var x = "<Hello, [play^ground+]>"
let y = x.replacingOccurrences(of: "[\\[\\]^+<>]", with: "7", options: .regularExpression, range: nil)
print(y)
Output:
7Hello, 7play7ground777
If the characters you wish to remove were to be adjacent to each other you could use the
stringByReplacingCharactersInRange:(NSRange) withString:(NSString *)
Other than that, I think just using the same function several times isn't that bad. It is much more readable than creating a big method to do the same in a more generic way.
Create an extension on String...
extension String {
func replacingOccurrences(of strings:[String], with replacement:String) -> String {
var newString = self
for string in strings {
newString = newString.replacingOccurrences(of: string, with: replacement)
}
return newString
}
}
Call it like this:
aString = aString.replacingOccurrences(of:['/', ':', '.'], with:"")