I have a paragraph (4 sentences) of text in an .plist array that loads into a UITextView.
By default, it presents the text how it is, as one big lump of text in a paragraph. I want to know if it is possible to split this up?
Such as Line 1: sdfafasfsafsa, then line 2: asfdsafs, line 3: adfsfsdfsdfa, etc.
Is there a way I can search for a . and then separate the lines accordingly? I would just edit the plist manually but there are hundreds of entries so it isn't easy to do.
NSString* tidiedString = [sourceString stringByReplacingOccurrencesOfString:#"." withString:#"\n"];
Update: OK, so more detail is coming through. You could use a regular expression - but if you're not familiar, the learning curve is a bit steep. Otherwise, as with other answers, crank through the list. You need to take care of whitespaces, empty lines etc. The following snippet isn't pretty, but will do the job.
NSString* sourceString = #"Hyperlinks can be great. They can also dilute your focus and tempt you into putting off what you most want to do. Here I chose to place links at the foot of the page to help you to make an active choice as to whether to surf or refocus your attention elsewhere.";
NSArray* arrayOfStrings = [sourceString componentsSeparatedByString:#"."];
NSMutableString* superString = [NSMutableString stringWithString:#""];
int lineCount = 1;
for (NSString* string in arrayOfStrings)
{
if ([string length] < 1) continue;
[superString appendFormat:#"Line %d: %#.\n", lineCount++, [string stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]];
}
[superString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[[self userEntry] setText:superString];
NSArray *array = [sourceString componentsSeparatedByString:#"."];
NSMutableString *resultString= [[NSMutableString alloc] init];
int linecount=1;
for(NSString *lines in array)
{
[resultString appendString:[NSString stringWithFormat:#"Line%i:%#\n",linecount++,lines]];
}
NSLog(#"resultString:%#",resultString);
this may help..!!
Try making a loop that runs through the array and that adds every line to the UITextView plus #"\n".
So something like...:
NSString *curText = txtView.text;
NSString *lineBreak = #"\n";
txtView.text=[NSString stringWithFormat:#"%# + %#", curText, lineBreak];
Or just replace the dots by #"\n".
Related
I am trying to get the first sentence of a text view. I have the following code but am getting an out of bounds error. Thank You. Or are there any ways that aren't really complex.
-(IBAction)next:(id)sender
{
NSRange ran = [[tv.text substringFromIndex:lastLocation] rangeOfString:#". "];
if(ran.location != NSNotFound)
{
NSString * getRidOfFirstHalfString = [[tv.text substringFromIndex:lastLocation] substringToIndex:ran.location];
NSLog(#"%#",getRidOfFirstHalfString);
lastLocation+=getRidOfFirstHalfString.length;
}
How about:
NSString *finalString = [[tv.text componentsSeparatedByString:#"."] objectAtIndex:0] // Get the 1st part (left part) of the separated string
Go through the textview's text and divide the text into separate components where you find a period by calling componentsSeperatedByString on tv.text. You want the first sentence, which would be the 0th object in the array.
I know you've already accepted an answer to this question, but you might want to consider using the text view's tokenizer instead of just searching for the string ". " The tokenizer will automatically handle punctuation like !, ?, and closing quotes. You can use it like this:
id<UITextInputTokenizer> tokenizer = textView.tokenizer;
UITextRange *range = [tokenizer rangeEnclosingPosition:textView.beginningOfDocument
withGranularity:UITextGranularitySentence
inDirection:UITextStorageDirectionForward];
NSString *firstSentence = [textView textInRange:range];
If you want to enumerate all of the sentences, you can do it like this:
id<UITextInputTokenizer> tokenizer = textView.tokenizer;
UITextPosition *start = textView.beginningOfDocument;
while (![start isEqual:textView.endOfDocument]) {
UITextPosition *end = [tokenizer positionFromPosition:start toBoundary:UITextGranularitySentence inDirection:UITextStorageDirectionForward];
NSString *sentence = [textView textInRange:[textView textRangeFromPosition:start toPosition:end]];
NSLog(#"sentence=%#", sentence);
start = end;
}
Try checking that the substring was actually found.
NSRange ran = [tv.text rangeOfString:#". "];
if(ran.location != NSNotFound)
{
NSString * selectedString = [tv.text substringToIndex:ran.location];
NSLog(#"%#",selectedString);
}
You could alternatively try using NSScanner like this:
NSString *firstSentence = [[NSString alloc] init];
NSScanner *scanner = [NSScanner scannerWithString:tv.text];
NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:#"."];
[scanner scanUpToCharactersFromSet:set intoString:&firstSentence];
I'm not sure if you want this, but since you want the first sentence, you could append a period (you probably know how to do this, but it doesn't hurt to show it anyway):
firstSentence = [firstSentence stringByAppendingFormat:#"."];
Hope this helps!
PS: If it didn't work for you, maybe the text view doesn't actually contain any text.
I have the following NSMutableString:
#"1*2*3*4*5"
I want to find the first * and remove everything after it, so my string = #"1"; How do I do this?
NSMutableString *string = [NSMutableString stringWithString:#"1*2*3*4*5"];
NSRange range = [string rangeOfString:#"*"];
if (range.location != NSNotFound)
{
[string deleteCharactersInRange:NSMakeRange(range.location, [string length] - range.location)];
}
You could try to divide this string by a separator and get the first object
NSString *result = [[MyString componentsSeparatedByString:#"*"]objectAtIndex:0];
After calling componentsSeparatedByString:#"*" you'll get the array of strings, separated by *,and the first object is right what you need.
Here's yet another strategy, using the very flexible NSScanner.
NSString* beginning;
NSScanner* scanner = [NSScanner scannerWithString:#"1*2*3*4*5"];
[scanner scanUpToString:#"*" intoString:&beginning];
You could use -rangeOfString: to find the index of the first asterisk and use that with -substringToIndex: to extract a substring from the original input. Something like this perhaps...
NSMutableString *input = #"1*2*3*4*5";
// Finds the range of the first instance. See NSString docs for more options.
NSRange firstAsteriskRange = [input rangeOfString:#"*"];
NSString *trimmedString = [input substringToIndex:firstAsteriskRange.location + 1];
How can I uppercase the fisrt letter of a NSString, and removing any accents ?
For instance, Àlter, Alter, alter should become Alter.
But, /lter, )lter, :lter should remains the same, as the first character is not a letter.
Please Do NOT use this method. Because one letter may have different count in different language. You can check dreamlax answer for that. But I'm sure that You would learn something from my answer.
NSString *capitalisedSentence = nil;
//Does the string live in memory and does it have at least one letter?
if (yourString && yourString.length > 0) {
// Yes, it does.
capitalisedSentence = [yourString stringByReplacingCharactersInRange:NSMakeRange(0,1)
withString:[[yourString substringToIndex:1] capitalizedString]];
} else {
// No, it doesn't.
}
Why should I care about the number of letters?
If you try to access (e.g NSMakeRange, substringToIndex etc)
the first character in an empty string like #"", then your app will crash. To avoid this you must verify that it exists before processing on it.
What if my string was nil?
Mr.Nil: I'm 'nil'. I can digest anything that you send to me. I won't allow your app to crash all by itself. ;)
nil will observe any method call you send to it.
So it will digest anything you try on it, nil is your friend.
You can use NSString's:
- (NSString *)capitalizedString
or (iOS 6.0 and above):
- (NSString *)capitalizedStringWithLocale:(NSLocale *)locale
Since you want to remove diacritic marks, you could use this method in combination with the common string manipulating methods, like this:
/* create a locale where diacritic marks are not considered important, e.g. US English */
NSLocale *locale = [[[NSLocale alloc] initWithLocaleIdentifier:#"en-US"] autorelease];
NSString *input = #"Àlter";
/* get first char */
NSString *firstChar = [input substringToIndex:1];
/* remove any diacritic mark */
NSString *folded = [firstChar stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:locale];
/* create the new string */
NSString *result = [[folded uppercaseString] stringByAppendingString:[input substringFromIndex:1]];
Gonna drop a list of steps which I think you can use to get this done. Hope you can follow through without a prob! :)
Use decomposedStringWithCanonicalMappingto decompose any accents (Important to make sure accented characters aren't just removed unnecessarily)
Use characterAtIndex: to extract the first letter (index 0), use upperCaseString to turn it into capitol lettering and use stringByReplacingCharactersInRange to replace the first letter back into the original string.
In this step, BEFORE turning it into uppercase, you can check whether the first letter is one of the characters you do not want to replace, e.g. ":" or ";", and if it is, do not follow through with the rest of the procedure.
Do a [theString stringByReplacingOccurrencesOfString:#"" withString:#""]` sort of call to remove any accents left over.
This all should both capitalize your first letter AND remove any accents :)
Since iOS 9.0 there is a method to capitalize string using current locale:
#property(readonly, copy) NSString *localizedCapitalizedString;
I'm using this method for similar situations but I'm not sure if question asked to make other letters lowercase.
- (NSString *)capitalizedOnlyFirstLetter {
if (self.length < 1) {
return #"";
}
else if (self.length == 1) {
return [self capitalizedString];
}
else {
NSString *firstChar = [self substringToIndex:1];
NSString *otherChars = [self substringWithRange:NSMakeRange(1, self.length - 1)];
return [NSString stringWithFormat:#"%#%#", [firstChar uppercaseString], [otherChars lowercaseString]];
}
}
Just for adding some options, I use this category to capitalize the first letter of a NSString.
#interface NSString (CapitalizeFirst)
- (NSString *)capitalizeFirst;
- (NSString *)removeDiacritic;
#end
#implementation NSString (CapitalizeFirst)
- (NSString *)capitalizeFirst {
if ( self.length <= 1 ) {
return [self uppercaseString];
}
else {
return [[[[self substringToIndex:1] removeDiacritic] uppercaseString] stringByAppendingString:[[self substringFromIndex:1] removeDiacritic]];
// Or: return [NSString stringWithFormat:#"%#%#", [[[self substringToIndex:1] removeDiacritic] uppercaseString], [[self substringFromIndex:1] removeDiacritic]];
}
}
- (NSString *)removeDiacritic { // Taken from: http://stackoverflow.com/a/10932536/1986221
NSData *data = [NSData dataUsingEncoding:NSASCIIStringEncoding
allowsLossyConversion:YES];
return [[NSString alloc] initWithData:data
encoding:NSASCIIStringEncoding];
}
#end
And then you can simply call:
NSString *helloWorld = #"hello world";
NSString *capitalized = [helloWorld capitalizeFirst];
NSLog(#"%# - %#", helloWorld, capitalized);
I have the follow code:
NSArray *myArray = [NSArray arrayWithObjects: #"e", #"è", #"é",#"i","ò",nil];
NSString *string = #"simpleè";
NSMutablestring *newString;
for(i=0>;i< [string length]; i++){
if([stringa characterAtIndex:i] is in Array){
[newString appendFormat:#"%c", [string characterAtIndex:i]];
}
}
How make finding if single char of string stay in the array?
Example of result:
newString= #"ieè";
I think you want to apply rangeOfCharacterFromSet:options:range: repeatedly. You'll have to create a NSCharacterSet from the characters in your array somehow.
Added
Though it probably would be just as simple to just loop through the string with characterAtIndex and compare each char (in an inner loop) to the chars in your array (which you could extract into a unichar array or put into a single NSString to make easier to access).
Umm... if you want to check what the values are you can use NSLog
NSLog"%f", myFloat;
So you can use this to check your array... Which is what I think you are asking for, but the grammar in your question isn't very good. Please provide more details and better grammar.
You should check the length of your string and then match your string characters with the array and if found append that character in a new string.
NSString *mstr = #"asdf";
NSString *b = [ mstr characterAtIndex:0];
Hope it helps.......
You'll want to create an NSCharacterSet with the characters in the string and then ask each string in the array for its rangeOfCharacterFromSet:. If you find one where a range was actually found, then a character from the string is in the array. If not, then none of them are.
This might seem a bit roundabout, but Unicode makes looking at strings as just a series of "chars" rather unreliable, and you'll want to let your libraries do as much of the heavy lifting for you as they can.
There are better ways to do this, but this is what I think you're trying to do:
NSMutableString* result= [NSMutableString stringWithString:#""];
for( int i= 0; i < [string length]; ++i ) {
NSString* c= [NSString stringWithFormat:#"%C", [string characterAtIndex:i]];
if( [myArray containsObject:c] )
[result appendString:c];
}
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How do I concatenate strings in Objective-C?
Firstly, the platform is iPhone and label.text changes the label displayed. Consider this scenario:
I've an array of integers. And I want to display it on the screen.
Here's my take on it:
-(IBAction) updateText: (id)sender {
int a[2];
a[0]=1;
a[1]=2;
a[2]=3;
for (int i=0; i<=10;i++)
label.text = [NSString stringByAppendingString: [NSString stringWithFormat: #"%i", a[i]]];
}
As you can probably see, I'm pretty confused. Pls pls help me out :(
Try this:
NSMutableString* theString = [NSMutableString string];
for (int i=0; i<=10;i++){
[theString appendString:[NSString stringWithFormat:#"%i ",i]];
}
label.text = theString;
Since you're using a loop, do be somewhat careful with both Tom and Benjie's solutions. They each create an extra autoreleased object per iteration. For a small loop, that's fine, but if the size of the loop is unbounded or if the strings are large, this can lead to a very large memory spike and performance hit. Particularly on iPhone, this is exactly the kind of loop that can lead to surprising memory problems due to short-lived memory spikes.
The following solution has a smaller memory footprint (it's also slightly faster and takes less typing). Note the call to -appendFormat: rather than -appendString. This avoids creating a second string that will be thrown away. Remember that the final string has an extra space at the end that you may want to get rid of. You can fix that by either treating the first or last iteration differently, or by trimming the last space after the loop.
NSMutableString* theString = [NSMutableString string];
for (int i=0; i<=10;i++){
[theString appendFormat:#"%i ",i];
}
label.text = theString;
Don't forget [NSArray componentsJoinedByString:]. In this case you don't have an NSArray, but in the common cases where you do, this is probably the best way to get what you're looking for.
//NSArray *chunks
string = [chunks componentsJoinedByString: #","];
Another method without using NSMutableString:
NSString* theString = #"";
for (int i=0; i<=10;i++){
theString = [theString stringByAppendingFormat:#"%i ",i];
}
label.text = theString;
Here's a full implementation (correcting your ranges):
-(IBAction) updateText: (id)sender {
int a[3];
a[0]=1;
a[1]=2;
a[2]=3;
NSString *str = #"";
for (int i=0; i<3;i++)
str = [str stringByAppendingFormat:#"%i ",i];
label.text = str;
}
You could also do it like this (e.g. if you wanted a comma separated list):
-(IBAction) updateText: (id)sender {
int a[3];
a[0]=1;
a[1]=2;
a[2]=3;
NSMutableArray *arr = [NSMutableArray arrayWithCapacity:3];
for (int i=0; i<3;i++)
[arr addObject:[NSString stringWithFormat:#"%i",i]];
label.text = [arr componentsJoinedByString:#", "];
}