Replacing Double quotes from json request objective c - ios

Stuck on below.
I am going to replace "" (Double quotes) from textfield text and send that text in json request parameter but below code is not working
NSString * mString = textfield.text; // Input through ipad/iphone/simulator keypad.
[mString replaceOccurrencesOfString:#"\"" withString:#"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [mString length])];.
But if i hardcode NSString * mString = #"\"test"; // Input through xcode
replaceOccurrencesOfString: is working.
Is the issue with Double quote Input encoding.?
Why does the Double quote from ipad/iphone/simulator keypad not working same as xcode Double quote.
Thanks.

By default, the iOS keyboard uses "smart" quotes... it uses left double quotation mark when you open a quoted string portion, and right double quotation mark when you close the quoted portion.
So to strip those, you'll need to replace double-quote AND left-double-quote AND right-double-quote.
Here's a quick example:
NSString *origString = _myTextField.text;
NSString *strippedString = [origString copy];
NSArray *replaceChars = #[#"”", #"“", #"\""];
for (NSString *c in replaceChars) {
strippedString = [strippedString
stringByReplacingOccurrencesOfString:c
withString:#""];
}
NSLog(#"Orig: [%#] / Stripped: [%#]", origString, strippedString);
Example output:
Orig: [“test”] / Stripped: [test]
You have to look close, but you'll see the left- and right-double-quote-marks.
Edit
A much more concise way:
NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:#"”“\""];
NSString *strippedString = [origString stringByTrimmingCharactersInSet:set];
NSLog(#"Orig: [%#] / Stripped: [%#]", origString, strippedString);
But, as noted by Sulthan, you may need to consider other languages' punctuation.

Related

Removing Specific Characters from NSString

For example if i had a string like
NSString *myString = #"A B C D E F G";
and I want to remove the spaces, and get a string out like "ABCDEFG".
I could use
NSString *stringWithoutSpaces = [myString stringByReplacingOccurrencesOfString:#" " withString:#""];
However, for my application I am loading in phone numbers from the address book
and the numbers often have a different formatting layout.
I'm wondering if I have a phone number stored in a string like
+1-(937)673-3451 how would I go about removing only the first "1" the "+" the "-" and the "(" ")".
Overall, I would like to know if it is possible to remove the first "1" without removing the last one in the string?
There are a lot of ways to do this. Here's one:
NSString *phoneNumber = #"+1-(937)673-3451";
NSCharacterSet *removalCharacterSet = [NSCharacterSet characterSetWithCharactersInString:#"+()-"];
NSArray *components = [phoneNumber componentsSeparatedByCharactersInSet:removalCharacterSet];
NSString *simplifiedPhoneNumber = [components componentsJoinedByString:#""];
NSRange firstCharacterRange = NSMakeRange(0, 1);
if ([[simplifiedPhoneNumber substringWithRange:firstCharacterRange] isEqualToString:#"1"]) {
simplifiedPhoneNumber = [simplifiedPhoneNumber stringByReplacingCharactersInRange:firstCharacterRange withString:#""];
}
NSLog(#"Full phone number: %#", phoneNumber);
NSLog(#"Simplified phone number: %#", simplifiedPhoneNumber);
But really you want to use a library that knows what a phone number is supposed to look like, like libPhoneNumber.

Regex to find strings in iOS source code

I need a regex to find string literals in iOS source code.
I want to collect them and then use in other place.
I need the regex to be able to parse next cases. Comments will be stripped beforehand:
char c = '"'; /* Not a string*/ NSString * *str1 = #"string"; // Here's a string
NSString *str2 = #"\"A\" class";
NSString *str3 = #"Long long"
#"long long string";
NSString *str4 = #"Another Long long"
"long long string";
NSString *str5 = #"Long untrimmed \
string";
I'm not very good with regex. I've tried this one:
#"(?<!')\"((\\\\\")*[^\"\\r\\n]*(\\\\\")*)*\"'{0}"
Unfortunately it hangs on such strings.
Hello here is your solution "(\\.|[^"])*\" use this regex to parse string literals in any text. you can check this regex on sample text on http://regexpal.com/
hope is helps !
#(\".*\";|\".*\n.*\";|\".*\")
Check http://rubular.com/r/6dxtBzTE7P . I could not do 3rd one fully correct.
I end up with following regex (^|[^'])(#?\"([^\"\\\\]|(\\\\.)|(\\\\\n)|(\"\\s*#?\"))*\"), example:
NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:#"(^|[^'])(#?\"([^\"\\\\]|(\\\\.)|(\\\\\n)|(\"\\s*#?\"))*\")" options:NSRegularExpressionAnchorsMatchLines error:&error];
[regex enumerateMatchesInString:source options:0 range:NSMakeRange(0, [source length]) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
NSLog(#"%#\n\n", [source substringWithRange:[result rangeAtIndex:2]]);
}];
It works fine for any cases that I have in my mind plus it also works for c-string.
How it works:
(^|[^']) Any character except ' (because '"') or beginning of line
#?\"([^\"\\\\]|(\\\\.)|(\\\\\n)|(\"(\\s*\\n*\\s*)*#?\"))*\" starts with #" or " and ends with ".
Between can be any sequence of character except " or \ ([^\"\\\\])
it can be \ char then skip next element too, it escaped anyway (\\\\.)
it can be escaped next line symbol (\\\\\n)
it can be multiline string, so we skip all whitespaces and new line symbols. Next line in string can be both from " and #" (#?\"\\s*#?\")
Check online editor: http://regex101.com/r/gG0sF2

Get the unique characters in an NSString

How can I get the unique characters in an NSString?
What I'm trying to do is get all the illegal characters in an NSString so that I can prompt the user which ones were inputted and therefore need to be removed. I start off by defining an NSCharacterSet of legal characters, separate them with every occurrence of a legal character, and join what's left (only illegal ones) into a new NSString. I'm now planning to get the unique characters of the new NSString (as an array, hopefully), but I couldn't find a reference anywhere.
NSCharacterSet *legalCharacterSet = [NSCharacterSet
characterSetWithCharactersInString:#"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ0123456789-()&+:;,'.# "];
NSString *illegalCharactersInTitle = [[self.titleTextField.text.noWhitespace
componentsSeparatedByCharactersInSet:legalCharacterSet]
componentsJoinedByString:#""];
That should help you. I couldn't find any ready to use function for that.
NSMutableSet *uniqueCharacters = [NSMutableSet set];
NSMutableString *uniqueString = [NSMutableString string];
[illegalCharactersInTitle enumerateSubstringsInRange:NSMakeRange(0, illegalCharactersInTitle.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
if (![uniqueCharacters containsObject:substring]) {
[uniqueCharacters addObject:substring];
[uniqueString appendString:substring];
}
}];
Try with the following adaptation of your code:
// legal set
NSCharacterSet *legalCharacterSet = [NSCharacterSet
characterSetWithCharactersInString:#"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ0123456789-()&+:;,'.# "];
// test strings
NSString *myString = #"LegalStrin()";
//NSString *myString = #"francesco#gmail.com"; illegal string
NSMutableCharacterSet *stringSet = [NSCharacterSet characterSetWithCharactersInString:myString];
// inverts the set
NSCharacterSet *illegalCharacterSet = [legalCharacterSet invertedSet];
// intersection of the string set and the illegal set that modifies the mutable stringset itself
[stringSet formIntersectionWithCharacterSet:illegalCharacterSet];
// prints out the illegal characters with the convenience method
NSLog(#"IllegalStringSet: %#", [self stringForCharacterSet:stringSet]);
I adapted the method to print from another stackoverflow question:
- (NSString*)stringForCharacterSet:(NSCharacterSet*)characterSet
{
NSMutableString *toReturn = [#"" mutableCopy];
unichar unicharBuffer[20];
int index = 0;
for (unichar uc = 0; uc < (0xFFFF); uc ++)
{
if ([characterSet characterIsMember:uc])
{
unicharBuffer[index] = uc;
index ++;
if (index == 20)
{
NSString * characters = [NSString stringWithCharacters:unicharBuffer length:index];
[toReturn appendString:characters];
index = 0;
}
}
}
if (index != 0)
{
NSString * characters = [NSString stringWithCharacters:unicharBuffer length:index];
[toReturn appendString:characters];
}
return toReturn;
}
First of all, you have to be careful about what you consider characters. The API of NSString uses the word characters when talking about what Unicode refers to as UTF-16 code units, but dealing with code units in isolation will not give you what users think of as characters. For example, there are combining characters that compose with the previous character to produce a different glyph. Also, there are surrogate pairs, which only make sense when, um, paired.
As a result, you will actually need to collect substrings which contain what the user thinks of as characters.
I was about to write code very similar to Grzegorz Krukowski's answer. He beat me to it, so I won't but I will add that your code to filter out the legal characters is broken because of the reasons I cite above. For example, if the text contains "é" and it's decomposed as "e" plus a combining acute accent, your code will strip the "e", leaving a dangling combining acute accent. I believe your intent is to treat the "é" as illegal.

Remove parentheses without regex

I need to turn something like this
NSString *stringWithParentheses = #"This string uses (something special)";
Into this, programmatically.
NSString *normalString = #"This string uses";
The issue is I don't want to use all these weird libraries, regex, etc.
If you change your mind about the regex, here's a short, clean solution:
NSString *foo = #"First part (remove) (me (and ((me)))))) (and me) too))";
NSRegularExpression *expr = [NSRegularExpression regularExpressionWithPattern:#"\\(.*\\)" options:0 error:NULL];
NSString *bar = [expr stringByReplacingMatchesInString:foo options:0 range:NSMakeRange(0, foo.length) withTemplate:#""];
Everything between ( and ) gets removed, including any nested parentheses and unmatched parentheses within parentheses.
Just find the first open parentheses, note its index, find the closing one, note its index, and remove the characters between the indexes (including the indexes themselves).
To find the character use:
[string rangeOfString:#"("];
To remove a range:
[string stringByReplacingCharactersInRange:... withString:#""];
Here is a solution:
NSString* str = #"This string uses (something special)";
NSRange rgMin = [str rangeOfString:#"("];
NSRange rgMax = [str rangeOfString:#")"];
NSRange replaceRange = NSMakeRange(rgMin.location, rgMax.location-rgMin.location+1);
NSString* newString = str;
if (rgMin.location < rgMax.location)
{
newString = [str stringByReplacingCharactersInRange:replaceRange withString:#""];
}
It won't work on nested parentheses. Or multiple parentheses. But it works on your example. This is to be refined to your exact situation.
A way would be to find the position of the first occurrence of the '(' character and the last occurrence of the ')' character, and to build a substring by eliminating all the characters between these ranges. I've made an example:
NSString* str= #"This string uses (something special)";
NSRange r1=[str rangeOfString: #"("];
NSRange r2= [str rangeOfString: #")" options: NSBackwardsSearch];
NSLog(#"%#",[str stringByReplacingCharactersInRange: NSMakeRange(r1.location, r2.location+r2.length-r1.location) withString: #""]);

How do I break in the NSArray with NSString substrings enclosed in quotes

I have a NSSring:
NSString *example = #"'example01','example02','example03','example04'";
How can I make from this line NSArray?
NSString *example = [example stringByReplacingOccurrencesOfString:#"'" withString:#""];
NSArray * exampleArr = [example componentsSeparatedByString:#","];
NSArray *commaSeparatedComponents = [example componentsSeparatedByString:#","];
NSCharacterSet *quotesSet = [NSCharacterSet characterSetWithCharactersInString:#"'"];
for (NSString *component in commaSeparatedComponents) {
NSString *correctlyTrimmedComponent = [component stringByTrimmingCharactersInSet:quotesSet]; // only remove 's at the edges
// ... do something with each component; maybe add to a mutable array ...
}
This has the advantage over the other answer to not remove quotes that exist inside the values, but it doesn't do anything to actually solve quotes escaping that might have been necessary inside the data, and so on. It still misbehaves with some strings, but it misbehaves for fewer cases because it is less flippant about which quotes it removes.
If this is anything above and beyond a string in that exact format, you will probably need a parser for this sort of string that can handle the semantics of how the quotes are escaped, gracefully handles garbage, etc.

Resources