Separate Full Sentences in a block of NSString text

I have been trying to use Regular Expression to separate full sentences in a big block of text. I can't use the componentsSeparatedByCharactersInSet because it will obviously fail with sentences ending in ?!, !!, ... I have seen some external classes to do componentSeparateByRegEx but I prefer doing it without adding an external library.

Here is a sample input <strong>Hi, I am testing. How are you? Wow!! this is the best, and I am happy.</strong>

The output should be an array

first element: <strong>Hi, I am testing.</strong>

second element: <strong>How are you?</strong>

third element: <strong>wow!!</strong>

forth element: <strong>this is the best, and I am happy.</strong>

This is what I have but as I mentioned it shouldn't do what I intend. Probably a regular expression will do a much better job here.

-(NSArray *)getArrayOfFullSentencesFromBlockOfText:(NSString *)textBlock{ NSMutableCharacterSet *characterSet = [[NSMutableCharacterSet alloc] init]; [characterSet addCharactersInString:@".?!"]; NSArray * sentenceArray = [textBlock componentsSeparatedByCharactersInSet:characterSet]; return sentenceArray; }

Thanks for your help,


You want to use -[NSString enumerateSubstringsInRange:options:usingBlock:] with the NSStringEnumerationBySentences option. This will give you every sentence, and it does so in a language-aware manner.

NSArray *fullSentencesFromText(NSString *text) { NSMutableArray *results = [NSMutableArray array]; [text enumerateSubstringsInRange:NSMakeRange(0, [text length]) options:NSStringEnumerationBySentences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) { [results addObject:substring]; }]; return results; }

Note, in testing, each substring appears to contain the trailing spaces after the punctuation. You may want to strip those out.


Something like this could do the job:

NSString *msg = @"Hi, I am testing. How are you? Wow!! this is the best, and I am happy."; [msg enumerateSubstringsInRange:NSMakeRange(0, [msg length]) options:NSStringEnumerationBySentences | NSStringEnumerationLocalized usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) { NSLog(@"Sentence:%@", substring); // Add each sentence into an array }];


Or use:

[mutstri enumerateSubstringsInRange:NSMakeRange(0, [mutstri length]) options:NSStringEnumerationBySentences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop){ NSLog(@"%@", substring); }];


  • TouchableHighlight press error
  • PHP - EC2 Implementing SES - Help
  • Comparing a string against a string read from input does not match in Rust [duplicate]
  • Why is a C++ Hello World binary larger than the equivalent C binary?
  • How to implement an IFilter for indexing heavyweight formats?
  • Zoom Effect Only Zooms Original Image Not New Image From Thumbnail
  • F#/C# - fsx Script Files and Project References
  • How can I prevent duplicate wrappers on a jQuery DataTable when navigating back in the presence of T
  • Understanding how to construct GHC.Generics Rep's and convert back to values
  • How do I read and write repeatedly from a process in vim?
  • What is wrong with this emulation of CMPXCHG16B instruction?
  • Django Migrations fail during django initialization
  • Whats the right place for testhelper-classes? (phpunit/best practise)
  • Making Cross Site Asynchronous HTTP Post from GWT Client
  • Raphael.js function getBBox give back NAN/NAN/NAN in IE8
  • matching similar elements in between two lists
  • IE10 strips out hashtag from the URL
  • Create a link to a web page that runs a Javascript function on the page
  • Fail:(TESTMODE) Transactions of this market type cannot be processed on this system
  • Button text different than value submitted in query string
  • C: Incompatible pointer type initializing
  • why xml file does not aligned properly after append the string in beginning and end of the file usin
  • Custom Tabgroup Appcelerator
  • iOS: Detect app start via notification press
  • Unity3D & Android: Difference between “UnityMain” and “main” threads?
  • Initializer list vs. initialization method
  • Why value captured by reference in lambda is broken? [duplicate]
  • output of program is not same as passed argument
  • Modifying destination and filename of gulp-svg-sprite
  • Knitr HTML Loop - Some HTML output, some R output
  • Deserializing XML into class C#
  • Weird JavaScript statement, what does it mean?
  • Function pointer “assignment from incompatible pointer type” only when using vararg ellipsis
  • Rearranging Cells in UITableView Bug & Saving Changes
  • Benchmarking RAM performance - UWP and C#
  • Angular 2 constructor injection vs direct access
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • python draw pie shapes with colour filled
  • Django query for large number of relationships
  • How to Embed XSL into XML