Transform punctuations form half width to full width - ios

I have a sentence below:
我今天去买菜,买了一个西瓜,花了1.2元,买了一个土豆,花了3.78元。还买了一个无花果,花了45.89,怎么办呢?好贵呀!贵的我不知道再买什么了。
The punctuations in it are half width. How to change them to fullwidth, like the following:
我今天去买菜,买了一个西瓜,花了1.2元,买了一个土豆,花了3.78元。还买了一个无花果,花了45.89,怎么办呢?好贵呀!贵的我不知道再买什么了。
Some punctuations to consider (not exhaustive):
, to ,
? to ?
! to !
"" to “”
; to ;

First, define the CharacterSet from which you want to transform your characters. So if you want only punctuation, the set could be CharacterSet.punctuationCharacters or CharacterSet.alphanumerics.inverted.
Then map each character from this set to its HalfwidthFullwidth transformation.
Swift 3 and 4
extension String {
func transformingHalfwidthFullwidth(from aSet: CharacterSet) -> String {
return String(characters.map {
if String($0).rangeOfCharacter(from: aSet) != nil {
let string = NSMutableString(string: String($0))
CFStringTransform(string, nil, kCFStringTransformFullwidthHalfwidth, true)
return String(string).characters.first!
} else {
return $0
}
})
}
}
Usage
let string = ",?!\"\";abc012図書館 助け 足場が痛い 多くの涙"
let result = string.transformingHalfwidthFullwidth(from: CharacterSet.alphanumerics.inverted)
// it prints: ,?!"";abc012図書館 助け 足場が痛い 多くの涙
print(result)
Objective-C
#implementation NSString (HalfwidthFullwidth)
- (NSString *)transformingHalfwidthFullwidth:(nonnull NSCharacterSet *)aSet {
NSUInteger len = self.length;
unichar buffer[len + 1];
[self getCharacters:buffer range:NSMakeRange(0, len)];
for (int i = 0; i < len; i++) {
unichar c = buffer[i];
NSMutableString *s = [[NSMutableString alloc] initWithCharacters:&c length:1];
NSRange r = [s rangeOfCharacterFromSet:aSet];
if (r.location != NSNotFound) {
CFStringTransform((CFMutableStringRef)s, nil, kCFStringTransformFullwidthHalfwidth, true);
[s getCharacters:buffer + i range:NSMakeRange(0, 1)];
}
}
return [NSString stringWithCharacters:buffer length:len];
}
#end
Usage
NSString *string = #",?!\"\";abc012図書館 助け 足場が痛い 多くの涙";
NSString *result = [string transformingHalfwidthFullwidth:NSCharacterSet.alphanumericCharacterSet.invertedSet];
// it prints: ,?!"";abc012図書館 助け 足場が痛い 多くの涙
NSLog(result);

you can use CFStringTransform like :
Objective C :
NSString *string = #" ? \"\"!我今天去买菜,买了一个西瓜,花了1.2元,买了一个土豆,花了3.78元。还买了一个无花果,花了45.89,怎么办呢?好贵呀!贵的我不知道再买什么了";
NSMutableString *convertedString = [string mutableCopy];
CFStringTransform((CFMutableStringRef)convertedString, NULL, kCFStringTransformFullwidthHalfwidth, true);
NSLog(#"%#",convertedString);
Swift 3.0 :
let string = NSMutableString( string: " ? \"\"!我今天去买菜,买了一个西瓜,花了1.2元,买了一个土豆,花了3.78元。还买了一个无花果,花了45.89,怎么办呢?好贵呀!贵的我不知道再买什么了" )
CFStringTransform( string, nil, kCFStringTransformFullwidthHalfwidth, true )
print(string)

Related

Trim last two lines of an attributed string

How do I remove the last two lines of this NSAttributedString?
NSString *exampleString = #"line 1\nline 2\nline 3\nline 4"
NSAttributedString *as = [NSAttributedString alloc] int];
[as setString:exampleString];
[self removeLastTwoLinesOfAttributedString:as];
NSLog(#"%#",as);
-(void)removeLastTwoLinesOfAttributedString:(NSAttributedString *)string {
//some code here
}
I'd like to end up with #"line 1\nline 2" in this example. Thanks
You could do something like this :
-(NSAttributedString *) removeLastTwoLinesOfAttributedString:(NSAttributedString *aString) {
NSRange range = [aString.string rangeOfString:#"\n" options:NSBackwardsSearch];
range = [aString.string rangeOfString:#"\n" options:NSBackwardsSearch range:NSMakeRange(0, range.location)];
return [aString attributedSubstringFromRange:NSMakeRange(0, range.location)];
}
int main (int argc, const char * argv[])
{
NSString *exampleString = #"line 1\nline 2\nline 3\nline 4";
NSAttributedString *as = [[NSAttributedString alloc] initWithString:exampleString];
as = [self removeLastTwoLinesOfAttributedString:as];
NSLog(#"%#",as);
return 0;
}
Output
line 1
line 2
I would suggest as the best solution:
-(NSAttributedString *)removeLastTwoLinesOfAttributedString:(NSAttributedString *)aString {
if (aString.length == 0) {
return aString
}
NSString *string = [aString string];
unsigned numberOfLines, index, stringLength = [string length];
NSRange rangeOfLastTwoLines = NSMakeRange(aString.length - 1, 0);
for (index = stringLength-1, numberOfLines = 0; index >= 0 && numberOfLines < 2; numberOfLines++) {
NSRange rangeOfLine = [string lineRangeForRange:NSMakeRange(index, 0)];
rangeOfLastTwoLines = NSUnionRange(rangeOfLastTwoLines, rangeOfLine);
index -= rangeOfLine.length;
}
return [aString attributedSubstringFromRange:NSMakeRange(0, rangeOfLastTwoLines.location)];
}
This has the benefit of working with any newline character not just "\n" and it uses the preferred by Apple method for detecting lines see this
Also it will not break if the last two lines are less than 2
If you're using Swift you can do this, if you're using Objective-C you should look at the other answers.
You can drop the last two lines of a String like this
string.components(separatedBy: "\n").dropLast(2).joined(separator: "\n")
To do it to an attributed string just access the string property, remove the last two lines, and create an attributed string with the trimmed string and all the same attributes.

Regular Expression and NSAttributedString to change colour of all the same words UILabel [duplicate]

There is a substring that occurs in a string several times. I use rangeOfString, but it seems that it can only find the first location. How can I find all the locations of the substring?
NSString *subString1 = #"</content>";
NSString *subString2 = #"--\n";
NSRange range1 = [newresults rangeOfString:subString1];
NSRange range2 = [newresults rangeOfString:subString2];
int location1 = range1.location;
int location2 = range2.location;
NSLog(#"%i",location1);
NSLog(#"%i",location2);
You can use rangeOfString:options:range: and set the third argument to be beyond the range of the first occurrence. For example, you can do something like this:
NSRange searchRange = NSMakeRange(0,string.length);
NSRange foundRange;
while (searchRange.location < string.length) {
searchRange.length = string.length-searchRange.location;
foundRange = [string rangeOfString:substring options:0 range:searchRange];
if (foundRange.location != NSNotFound) {
// found an occurrence of the substring! do stuff here
searchRange.location = foundRange.location+foundRange.length;
} else {
// no more substring to find
break;
}
}
Swift 3.0
Find all locations of substring i
let text = "This is the text and i want to replace something"
let mutableAttributedString = NSMutableAttributedString(string: text)
var searchRange = NSRange(location: 0, length: text.characters.count)
var foundRange = NSRange()
while searchRange.location < text.characters.count {
searchRange.length = text.characters.count - searchRange.location
foundRange = (text as NSString).range(of: "i", options: NSString.CompareOptions.caseInsensitive, range: searchRange)
if foundRange.location != NSNotFound {
// found an occurrence of the substring! do stuff here
searchRange.location = foundRange.location + foundRange.length
mutableAttributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: foundRange)
}
else {
// no more substring to find
break
}
}
//Apply
textLabel.attributedText = mutableAttributedString;
And this output-
This is my solution. Basically, the algorithm traverses the string looking for substring matches and returns those matches in an array.
Since an NSRange is a struct it cannot be added to the array directly. By using NSValue, I can encode the match first and then add it to the array. To retrieve the range, I then decode the NSValue object to an NSRange.
#import <Foundation/Foundation.h>
NSRange makeRangeFromIndex(NSUInteger index, NSUInteger length) {
return NSMakeRange(index, length - index);
}
NSArray<NSValue *> * allLocationsOfStringMatchingSubstring(NSString *text, NSString *pattern) {
NSMutableArray *matchingRanges = [NSMutableArray new];
NSUInteger textLength = text.length;
NSRange match = makeRangeFromIndex(0, textLength);
while(match.location != NSNotFound) {
match = [text rangeOfString:pattern options:0L range:match];
if (match.location != NSNotFound) {
NSValue *value = [NSValue value:&match withObjCType:#encode(NSRange)];
[matchingRanges addObject:value];
match = makeRangeFromIndex(match.location + 1, textLength);
}
}
return [matchingRanges copy];
}
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSString *text = #"TATACCATGGGCCATCATCATCATCATCATCATCATCATCATCACAG";
NSString *pattern = #"CAT";
NSArray<NSValue *> *matches = allLocationsOfStringMatchingSubstring(text, pattern);
NSLog(#"Text: %#", text);
NSLog(#"Pattern: %#", pattern);
NSLog(#"Number of matches found: %li", matches.count);
[matches enumerateObjectsUsingBlock:^(NSValue *obj, NSUInteger idx, BOOL *stop) {
NSRange match;
[obj getValue:&match];
NSLog(#" Match found at index: %li", match.location);
}];
}
return 0;
}
Passing nil to [string rangeOfString:substring options:nil range:searchRange]; shows a warning.
To get rid of the warning, put in an enum from this group
enum {
NSCaseInsensitiveSearch = 1,
NSLiteralSearch = 2,
NSBackwardsSearch = 4,
NSAnchoredSearch = 8,
NSNumericSearch = 64,
NSDiacriticInsensitiveSearch = 128,
NSWidthInsensitiveSearch = 256,
NSForcedOrderingSearch = 512,
NSRegularExpressionSearch = 1024
};
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/index.html#//apple_ref/doc/constant_group/Search_and_Comparison_Options
Here is a version in Swift 2.2 of PengOne's answer with input from kevinlawler and Gibtang
Note: string and substring are of type NSString
let fullStringLength = (string as String).characters.count
var searchRange = NSMakeRange(0, fullStringLength)
while searchRange.location < fullStringLength {
searchRange.length = fullStringLength - searchRange.location
let foundRange = string.rangeOfString(substring as String, options: .CaseInsensitiveSearch, range: searchRange)
if foundRange.location != NSNotFound {
// found an occurrence of the substring! do stuff here
searchRange.location = foundRange.location + 1
} else {
// no more strings to find
break
}
}
I suggest using regular expression because it's a more declarative way and has fewer lines of code to write.
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"%#" options:nil error:nil];
NSString *toSearchStr = #"12312 %# Text %# asdsa %#";
__block int occurs = 0;
[regex enumerateMatchesInString:toSearchStr options:0 range:NSMakeRange(0, toSearchStr.length) usingBlock:^(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL * _Nonnull stop) {
occurs++;
}];
// occurs == 3

How to get the first alphabet character of a string in iOS

I have an example NSString in iOS
NSString* str = #"-- This is an example string";
I want to get the first alphabet letter. The result of above situation is letter "T" from word "This". Some characters before letter "T" is not alphabet letter so it returns the first alphabet letter is "T".
How can I retrieve it? If the string not contain any alphabet letter, it can return nil.
Besides, the result can be a NSRange
NSRange range = [string rangeOfCharacterFromSet:[NSCharacterSet letterCharacterSet]];
First create a NSCharecterSet as a global variable and write this code
-(void)viewDidLoad{
NSCharacterSet *s = [NSCharacterSet characterSetWithCharactersInString:#"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]
s = [s invertedSet];
NSString *myString = #"--- This is a string";
NSArray *arrayOfStrings = [myString componentsSeparatedByString:#" "];
for(int i=0;i<arrayOfStrings.count){
NSString *current = [arrayOfStrings objectAtIndex:i];
char c = [self returnCharacter:current];
if(c == nil){
//that means first word is not with alphabets;
}
else {
NSLog(#"%c",c);
//your output.
}
}
}
And here is the method
-(char)returnChracter:(NSString*)string{
NSRange r = [string rangeOfCharacterFromSet:s];
if (r.location != NSNotFound) {
NSLog(#"the string contains illegal characters");
return nil;
}
else {
//string contains all alphabets
char firstLetter = [string charAtIndex:0];
return firstLetter;
}
}
You can use the following function. Pass a string and get first character as a string.
-(NSString*)getFirstCharacter:(NSString*)string
{
for(int i=0;i<string.length;i++)
{
unichar firstChar = [string characterAtIndex:i];
NSCharacterSet *letters = [NSCharacterSet letterCharacterSet];
if ([letters characterIsMember:firstChar]) {
return [NSString:stringWithFormat:#"%c",firstChar];
}
}
return nil;
}

How to display hyphen in uilabel?

How to display hyphen with UILabel like this, - A I origine - , Here I use the string appending method. I get this type of output - À l'origine de la guerre -. But I want display hyphen before the starting point of text and display hyphen after 10 charatcers.
I was searched but i can't get valied source. kindly give any suggestion if you know.
NSString *tempStr = #" - ";
tempStr = [tempStr stringByAppendingString:NSLocalizedString(#"OriginallyWar", #"")];
tempStr = [tempStr stringByAppendingString:#" -"];
[headingLabel setText:tempStr];
[headingLabel setFont:MRSEAVES_BOLD(17)];
Use NSMutableString and insert characters,
[yourString insertString:#"-" atIndex:10];
if you are using StoryBoard directly set it to the text property on Attribute inspector. Put 10 empty spaces after the end of character and the -.
You may try this code
NSString *inputString = #"OriginallyWarDFdfsdfdDFSDfdsfdsfDFdsfadsfawerdsaf";
NSMutableString *localizedInputString = [NSMutableString stringWithString:NSLocalizedString(inputString, #"")];
int numberOfCharacters = localizedInputString.length;
int numberOf10s = (numberOfCharacters/10 + 1);
int numberOfCharactersToBeInserted = 0;
for (int i = 1; i < numberOf10s; i++) {
int characterIndex = (i * 10) + numberOfCharactersToBeInserted;
if (i == (numberOf10s - 1) && numberOfCharacters % 10 == 0) {
[localizedInputString insertString:#" -" atIndex:characterIndex];
numberOfCharactersToBeInserted = 2 * i;
} else {
[localizedInputString insertString:#" - " atIndex:characterIndex];
numberOfCharactersToBeInserted = 3 * i;
}
}
if (numberOfCharacters == 0) {
[localizedInputString insertString:#"-" atIndex:0];
} else {
[localizedInputString insertString:#"- " atIndex:0];
}
NSLog(#"localizedInputString : %#", localizedInputString);
try using NSMutableString
NSString *tempStr = #" - ";
tempStr = [tempStr stringByAppendingString:NSLocalizedString(#"OriginallyWar", #"")];
NSMutableString *tempStrMutable=[[NSMutableString alloc]initWithString:tempStr];
[tempStrMutable insertString:#"-" atIndex:10];
[headingLabel setText:tempStrMutable];

Encode NSString for XML/HTML

Is there a way to HTML encode a string (NSString) in Objective-C, something along the lines of Server.HtmlEncode in .NET?
There isn't an NSString method that does that. You'll have to write your own function that does string replacements. It is sufficient to do the following replacements:
'&' => "&"
'"' => """
'\'' => "'"
'>' => ">"
'<' => "<"
Something like this should do (haven't tried):
[[[[[myStr stringByReplacingOccurrencesOfString: #"&" withString: #"&"]
stringByReplacingOccurrencesOfString: #"\"" withString: #"""]
stringByReplacingOccurrencesOfString: #"'" withString: #"'"]
stringByReplacingOccurrencesOfString: #">" withString: #">"]
stringByReplacingOccurrencesOfString: #"<" withString: #"<"];
I took Mike's work and turn it into a category for NSMutableString and NSString
Make a Category for NSMutableString with:
- (NSMutableString *)xmlSimpleUnescape
{
[self replaceOccurrencesOfString:#"&" withString:#"&" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:#""" withString:#"\"" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:#"'" withString:#"'" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:#"'" withString:#"'" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:#"’" withString:#"'" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:#"–" withString:#"-" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:#">" withString:#">" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:#"<" withString:#"<" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
return self;
}
- (NSMutableString *)xmlSimpleEscape
{
[self replaceOccurrencesOfString:#"&" withString:#"&" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:#"\"" withString:#""" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:#"'" withString:#"'" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:#">" withString:#">" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:#"<" withString:#"<" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
return self;
}
Make a Category for NSString with:
- (NSString *)xmlSimpleUnescapeString
{
NSMutableString *unescapeStr = [NSMutableString stringWithString:self];
return [unescapeStr xmlSimpleUnescape];
}
- (NSString *)xmlSimpleEscapeString
{
NSMutableString *escapeStr = [NSMutableString stringWithString:self];
return [escapeStr xmlSimpleEscape];
}
* A Swift 2.0 Version *
The Objective-C version is a little more efficient as it does mutable operations on the string. However, this is a swift way to do simple escaping:
extension String
{
typealias SimpleToFromRepalceList = [(fromSubString:String,toSubString:String)]
// See http://stackoverflow.com/questions/24200888/any-way-to-replace-characters-on-swift-string
//
func simpleReplace( mapList:SimpleToFromRepalceList ) -> String
{
var string = self
for (fromStr, toStr) in mapList {
let separatedList = string.componentsSeparatedByString(fromStr)
if separatedList.count > 1 {
string = separatedList.joinWithSeparator(toStr)
}
}
return string
}
func xmlSimpleUnescape() -> String
{
let mapList : SimpleToFromRepalceList = [
("&", "&"),
(""", "\""),
("'", "'"),
("'", "'"),
("’", "'"),
("–", "-"),
(">", ">"),
("<", "<")]
return self.simpleReplace(mapList)
}
func xmlSimpleEscape() -> String
{
let mapList : SimpleToFromRepalceList = [
("&", "&"),
("\"", """),
("'", "'"),
(">", ">"),
("<", "<")]
return self.simpleReplace(mapList)
}
}
I could have used the NSString bridging capabilities to write something very similar to the NSString version, but I decided to do it more swifty.
I use Google Toolbox for Mac (works on iPhone). In particular, see the additions to NSString in GTMNSString+HTML.h and GTMNSString+XML.h.
For URL encoding:
NSString * encodedString = [originalString
stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
See Apple's NSString documentation for more info.
For HTML encoding:
Check out CFXMLCreateStringByEscapingEntities, which is part of the Core Foundation XML library, but should still do the trick.
the samets's routine forgot the hex digit. Here's the routine I came up with that works:
- (NSString*)convertEntities:(NSString*)string
{
NSString *returnStr = nil;
if( string )
{
returnStr = [ string stringByReplacingOccurrencesOfString:#"&" withString: #"&" ];
returnStr = [ returnStr stringByReplacingOccurrencesOfString:#""" withString:#"\"" ];
returnStr = [ returnStr stringByReplacingOccurrencesOfString:#"'" withString:#"'" ];
returnStr = [ returnStr stringByReplacingOccurrencesOfString:#"9" withString:#"'" ];
returnStr = [ returnStr stringByReplacingOccurrencesOfString:#"’" withString:#"'" ];
returnStr = [ returnStr stringByReplacingOccurrencesOfString:#"–" withString:#"'" ];
returnStr = [ returnStr stringByReplacingOccurrencesOfString:#">" withString:#">" ];
returnStr = [ returnStr stringByReplacingOccurrencesOfString:#"<" withString:#"<" ];
returnStr = [ [ NSString alloc ] initWithString:returnStr ];
}
return returnStr;
}
If you can use NSXMLNode (on OS X) Here is the trick:
NSString *string = #"test<me>"
NSXMLNode *textNode = [NSXMLNode textWithStringValue:string];
NSString *escapedString = [textNode.XMLString];
Swift 4
extension String {
var xmlEscaped: String {
return replacingOccurrences(of: "&", with: "&")
.replacingOccurrences(of: "\"", with: """)
.replacingOccurrences(of: "'", with: "'")
.replacingOccurrences(of: ">", with: ">")
.replacingOccurrences(of: "<", with: "<")
}
}
Here is a more efficient implementation of this xml escape logic.
+ (NSString*) xmlSimpleEscape:(NSString*)unescapedStr
{
if (unescapedStr == nil || [unescapedStr length] == 0) {
return unescapedStr;
}
const int len = [unescapedStr length];
int longer = ((int) (len * 0.10));
if (longer < 5) {
longer = 5;
}
longer = len + longer;
NSMutableString *mStr = [NSMutableString stringWithCapacity:longer];
NSRange subrange;
subrange.location = 0;
subrange.length = 0;
for (int i = 0; i < len; i++) {
char c = [unescapedStr characterAtIndex:i];
NSString *replaceWithStr = nil;
if (c == '\"')
{
replaceWithStr = #""";
}
else if (c == '\'')
{
replaceWithStr = #"'";
}
else if (c == '<')
{
replaceWithStr = #"<";
}
else if (c == '>')
{
replaceWithStr = #">";
}
else if (c == '&')
{
replaceWithStr = #"&";
}
if (replaceWithStr == nil) {
// The current character is not an XML escape character, increase subrange length
subrange.length += 1;
} else {
// The current character will be replaced, but append any pending substring first
if (subrange.length > 0) {
NSString *substring = [unescapedStr substringWithRange:subrange];
[mStr appendString:substring];
}
[mStr appendString:replaceWithStr];
subrange.location = i + 1;
subrange.length = 0;
}
}
// Got to end of unescapedStr so append any pending substring, in the
// case of no escape characters this will append the whole string.
if (subrange.length > 0) {
if (subrange.location == 0) {
[mStr appendString:unescapedStr];
} else {
NSString *substring = [unescapedStr substringWithRange:subrange];
[mStr appendString:substring];
}
}
return [NSString stringWithString:mStr];
}
+ (NSString*) formatSimpleNode:(NSString*)tagname value:(NSString*)value
{
NSAssert(tagname != nil, #"tagname is nil");
NSAssert([tagname length] > 0, #"tagname is the empty string");
if (value == nil || [value length] == 0) {
// Certain XML parsers don't like empty nodes like "<foo/>", use "<foo />" instead
return [NSString stringWithFormat:#"<%# />", tagname];
} else {
NSString *escapedValue = [self xmlSimpleEscape:value];
return [NSString stringWithFormat:#"<%#>%#</%#>", tagname, escapedValue, tagname];
}
}
Here is my swift category for html encoding/decoding:
extension String
{
static let htmlEscapedDictionary = [
"&": "&",
""" : "\"",
"'" : "'",
"9" : "'",
"’" : "'",
"–" : "'",
">" : ">",
"<" : "<"]
var escapedHtmlString : String {
var newString = "\(self)"
for (key, value) in String.htmlEscapedDictionary {
newString.replace(value, withString: key)
}
return newString
}
var unescapedHtmlString : String {
let encodedData = self.dataUsingEncoding(NSUTF8StringEncoding)!
let attributedOptions : [String: AnyObject] = [
NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: NSUTF8StringEncoding
]
let attributedString = NSAttributedString(data: encodedData, options: attributedOptions, documentAttributes: nil, error: nil)!
return attributedString.string
}
mutating func replace(originalString:String, withString newString:String)
{
let replacedString = self.stringByReplacingOccurrencesOfString(originalString, withString: newString, options: nil, range: nil)
self = replacedString
}
}
I guess a reverse of htmlEscapedDictionary could've been used as well in unescapedHtmlString
Note: As MarkBau pointed out in the comment below: Since Swift does not guarantee the order of dictionaries, make sure to replace & first.
I put together a quick example project using Mike and Tod's answers here.
Makes the encoding/unencoding dead simple:
NSString *html = #"<p>This \"paragraph\" contains quoted & 'single' quoted stuff.</p>";
NSLog(#"Original String: %#", html);
NSString *escapedHTML = [html xmlSimpleEscapeString];
NSLog(#"Escaped String: %#", escapedHTML);
NSString *unescapedHTML = [escapedHTML xmlSimpleUnescapeString];
NSLog(#"Unescaped String: %#", unescapedHTML);
This easiest solution is to create a category as below:
Here’s the category’s header file:
#import <Foundation/Foundation.h>
#interface NSString (URLEncoding)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding;
#end
And here’s the implementation:
#import "NSString+URLEncoding.h"
#implementation NSString (URLEncoding)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)#"!*'\"();:#&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(encoding));
}
#end
And now we can simply do this:
NSString *raw = #"hell & brimstone + earthly/delight";
NSString *url = [NSString stringWithFormat:#"http://example.com/example?param=%#",
[raw urlEncodeUsingEncoding:NSUTF8StringEncoding]];
NSLog(url);
The credits for this answer goes to the website below:-
http://madebymany.com/blog/url-encoding-an-nsstring-on-ios
Refer below answer:
NSString *content = global.strPrivacyPolicy;
content = [[[[[content stringByReplacingOccurrencesOfString: #"&" withString: #"&"]
stringByReplacingOccurrencesOfString:#""" withString:#"\" "]
stringByReplacingOccurrencesOfString: #"'" withString:#"'"]
stringByReplacingOccurrencesOfString: #">" withString: #">"]
stringByReplacingOccurrencesOfString: #"<" withString:#"<"];
[_webViewPrivacy loadHTMLString:content baseURL:nil];
Use the message in the example below :
anyStringConverted = [anyString stringByReplacingOccurrencesOfString:#"\n" withString:#"<br>"];
This converts 'new line' command to corresponding html code. But to convert symbols, you have to write the corresponding html number.
You can see the complete list of html numbers here at
http://www.ascii.cl/htmlcodes.htm
I found the only way that uses only built-in functions (not manual parsing) and covers all cases. Requires AppKit/UIKit in addition to Foundation. This is Swift but can easily be Objective-C:
func encodedForHTML() -> String {
// make a plain attributed string and then use its HTML write functionality
let attrStr = NSAttributedString(string: self)
// by default, the document outputs a whole HTML element
// warning: if default apple implementation changes, this may need to be tweaked
let options: [NSAttributedString.DocumentAttributeKey: Any] = [
.documentType: NSAttributedString.DocumentType.html,
.excludedElements: [
"html",
"head",
"meta",
"title",
"style",
"p",
"body",
"font",
"span"
]
]
// generate data and turn into string
let data = try! attrStr.data(from: NSRange(location: 0, length: attrStr.length), documentAttributes: options)
let str = String(data: data, encoding: .utf8)!
// remove <?xml line
return str.components(separatedBy: .newlines).dropFirst().first!
}

Resources