macOS NSString Regular Expressions: what changed
Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.
| Old | New | Line | |
|---|---|---|---|
| 1 | 1 | ## Regular expressions | |
| 2 | 2 | ||
| 3 | 3 | Regular expressions are patterns used to match specified alpha-numeric character combinations in the string data being searched. | |
| 4 | 4 | ||
| 5 | 5 | Each character in a regular expression (that is, each character in the string describing its pattern) is either a metacharacter or operator, having a special meaning, or a regular character that has a literal meaning. | |
| 6 | 6 | ||
| 7 | 7 | Regular expressions can be incredibly complex. Indeed, whole books have been written about them! For a gentle introduction to regular expressions, see this [O'Reilly article](https://www.oreilly.com/content/an-introduction-to-regular-expressions/). | |
| 8 | 8 | ||
| 9 | 9 | ## NSString Regular Expression Overview | |
| 10 | 10 | ||
| 11 | 11 | It is a little known fact that you can use regular expressions to match and replace patterns without having to resort to the more sophisticated, but complicated, [[macOS NSRegularExpression|NSRegularExpression]]: NSString has the *rangeOfString:options:range:* method for matching patterns and the *stringByReplacingOccurrencesOfString:withString:* method for replacing patterns. These are demonstrated in the examples below. | |
| 12 | 12 | ||
| 13 | 13 | ### Metacharacters | |
| 14 | 14 | ||
| 15 | 15 | For a comprehensive list of characters used that have a special meaning in regular expression patterns, see the [ICU listing](https://unicode-org.github.io/icu/userguide/strings/regexp.html#regular-expression-metacharacters). | |
| 16 | 16 | ||
| 17 | 17 | ### Operators | |
| 18 | 18 | ||
| 19 | 19 | For a comprehensive list of regular expression operators, see the [ICU listing](https://unicode-org.github.io/icu/userguide/strings/regexp.html#regular-expression-operators). | |
| 20 | 20 | ||
| 21 | 21 | ## Example 1 - match a pattern | |
| 22 | 22 | ||
| 23 | 23 | ### Code | |
| 24 | 24 | ||
| 25 | 25 | ``` pascal | |
| 26 | 26 | Program regex_ex1; | |
| 27 | 27 | ||
| 28 | 28 | {$mode objfpc}{$H+} | |
| 29 | 29 | {$modeswitch objectivec2} | |
| 30 | 30 | ||
| 31 | 31 | Uses | |
| 32 | 32 | MacOSAll, CocoaAll, SysUtils; | |
| 33 | 33 | ||
| 34 | 34 | Var | |
| 35 | 35 | srchStr : String; | |
| 36 | 36 | patnStr : String; | |
| 37 | 37 | i: NSRange; | |
| 38 | 38 | j: NSRange; | |
| 39 | 39 | ||
| 40 | 40 | Begin | |
| 41 | 41 | srchStr := 'I have 43 bags of 60 marbles.'; | |
| 42 | 42 | patnStr := '\d+'; | |
| 43 | 43 | ||
| 44 | 44 | // Find first match | |
| 45 | 45 | i := NSStr(srchStr).rangeOfString_options_range(NSStr(patnStr), (NSRegularExpressionSearch or NSCaseInsensitiveSearch), NSMakeRange(0, srchStr.Length)); | |
| 46 | 46 | ||
| 47 | 47 | // Find second match | |
| 48 | 48 | j := NSStr(srchStr).rangeOfString_options_range(NSStr(patnStr), (NSRegularExpressionSearch or NSCaseInsensitiveSearch), NSMakeRange(i.location + i.length, srchStr.Length - (i.location + i.length))); | |
| 49 | 49 | ||
| 50 | 50 | // Output | |
| 51 | 51 | NSLog(NSStr('Search string: %@'), NSStr(srchStr)); | |
| 52 | 52 | NSLog(NSStr('Pattern string: %@'), NSStr(patnStr)); | |
| 53 | 53 | ||
| 54 | 54 | NSLog(NSStr('Range 1: %@'), NSStringFromRange(i)); | |
| 55 | 55 | NSLog(NSStr('Location: %d'), i.location); | |
| 56 | 56 | NSLog(NSStr('Length: %d'), i.length); | |
| 57 | 57 | NSLog(NSStr('Match: %@'), NSStr(srchStr).substringWithRange(i)); | |
| 58 | 58 | ||
| 59 | 59 | NSLog(NSStr('Range 2: %@'), NSStringFromRange(j)); | |
| 60 | 60 | NSLog(NSStr('Location: %d'), j.location); | |
| 61 | 61 | NSLog(NSStr('Length: %d'), j.length); | |
| 62 | 62 | NSLog(NSStr('Match: %@'), NSStr(srchStr).substringWithRange(j)); | |
| 63 | 63 | End. | |
| 64 | 64 | ``` | |
| 65 | 65 | ||
| 66 | 66 | ### Output | |
| 67 | 67 | ||
| 68 | - | ||
| 69 | - | ||
| 70 | - | ||
| 71 | - | ||
| 72 | - | ||
| 73 | - | ||
| 74 | - | ||
| 75 | - | ||
| 76 | - | ||
| 77 | - | ||
| 68 | + | ```text | |
| 69 | + | 2021-06-15 21:43:49.049 regex_ex1[23182:177970] Search string: I have 43 bags of 60 marbles. | |
| 70 | + | 2021-06-15 21:43:49.049 regex_ex1[23182:177970] Pattern string: \d+ | |
| 71 | + | 2021-06-15 21:43:49.049 regex_ex1[23182:177970] Range 1: {7, 2} | |
| 72 | + | 2021-06-15 21:43:49.049 regex_ex1[23182:177970] Location: 7 | |
| 73 | + | 2021-06-15 21:43:49.049 regex_ex1[23182:177970] Length: 2 | |
| 74 | + | 2021-06-15 21:43:49.049 regex_ex1[23182:177970] Match: 43 | |
| 75 | + | 2021-06-15 21:43:49.049 regex_ex1[23182:177970] Range 2: {18, 2} | |
| 76 | + | 2021-06-15 21:43:49.049 regex_ex1[23182:177970] Location: 18 | |
| 77 | + | 2021-06-15 21:43:49.049 regex_ex1[23182:177970] Length: 2 | |
| 78 | + | 2021-06-15 21:43:49.049 regex_ex1[23182:177970] Match: 60 | |
| 79 | + | ``` | |
| 78 | 80 | ||
| 79 | 81 | ## Example 2 - replace matched pattern | |
| 80 | 82 | ||
| 81 | 83 | ### Code | |
| 82 | 84 | ||
| 83 | 85 | ``` pascal | |
| 84 | 86 | Program regex_ex2; | |
| 85 | 87 | ||
| 86 | 88 | {$mode objfpc}{$H+} | |
| 87 | 89 | {$modeswitch objectivec2} | |
| 88 | 90 | ||
| 89 | 91 | Uses | |
| 90 | 92 | MacOSAll, CocoaAll, SysUtils; | |
| 91 | 93 | ||
| 92 | 94 | Var | |
| 93 | 95 | srchStr : NSString; | |
| 94 | 96 | patnStr : NSString; | |
| 95 | 97 | resStr : NSString; | |
| 96 | 98 | i: NSRange; | |
| 97 | 99 | j: NSRange; | |
| 98 | 100 | ||
| 99 | 101 | Begin | |
| 100 | 102 | srchStr := NSStr('I have 43 bags of 60 marbles.'); | |
| 101 | 103 | patnStr := NSStr('\d+'); | |
| 102 | 104 | ||
| 103 | 105 | // Find first match | |
| 104 | 106 | i := srchStr.rangeOfString_options_range(patnStr, NSRegularExpressionSearch, NSMakeRange(0, srchStr.Length)); | |
| 105 | 107 | ||
| 106 | 108 | // Do first replacement | |
| 107 | 109 | resStr := srchStr.stringByReplacingOccurrencesOfString_withString(NSStr('43'), NSStr('forty-three')); | |
| 108 | 110 | ||
| 109 | 111 | // Find second match | |
| 110 | 112 | j := srchStr.rangeOfString_options_range(patnStr, NSRegularExpressionSearch, NSMakeRange(i.location + i.length, srchStr.Length - (i.location + i.length))); | |
| 111 | 113 | ||
| 112 | 114 | // Do second replacement | |
| 113 | 115 | resStr := resStr.stringByReplacingOccurrencesOfString_withString(NSStr('60'), NSStr('sixty')); | |
| 114 | 116 | ||
| 115 | 117 | // Output | |
| 116 | 118 | NSLog(NSStr('Search string: %@'), srchStr); | |
| 117 | 119 | NSLog(NSStr('Pattern string: %@'), patnStr); | |
| 118 | 120 | ||
| 119 | 121 | NSLog(NSStr('Range 1: %@'), NSStringFromRange(i)); | |
| 120 | 122 | NSLog(NSStr('Location: %d'), i.location); | |
| 121 | 123 | NSLog(NSStr('Length: %d'), i.length); | |
| 122 | 124 | NSLog(NSStr('Match: %@'), srchStr.substringWithRange(i)); | |
| 123 | 125 | ||
| 124 | 126 | NSLog(NSStr('Range 2: %@'), NSStringFromRange(j)); | |
| 125 | 127 | NSLog(NSStr('Location: %d'), j.location); | |
| 126 | 128 | NSLog(NSStr('Length: %d'), j.length); | |
| 127 | 129 | NSLog(NSStr('Match: %@'), srchStr.substringWithRange(j)); | |
| 128 | 130 | ||
| 129 | 131 | NSLog(NSStr('Result: %@'), resStr); | |
| 130 | 132 | End. | |
| 131 | 133 | ``` | |
| 132 | 134 | ||
| 133 | 135 | ### Output | |
| 134 | 136 | ||
| 135 | - | ||
| 136 | - | ||
| 137 | - | ||
| 138 | - | ||
| 139 | - | ||
| 140 | - | ||
| 141 | - | ||
| 142 | - | ||
| 143 | - | ||
| 144 | - | ||
| 145 | - | ||
| 137 | + | ```text | |
| 138 | + | 2021-06-16 11:41:24.025 regex_ex2[5761:21687] Search string: I have 43 bags of 60 marbles. | |
| 139 | + | 2021-06-16 11:41:24.026 regex_ex2[5761:21687] Pattern string: \d+ | |
| 140 | + | 2021-06-16 11:41:24.026 regex_ex2[5761:21687] Range 1: {7, 2} | |
| 141 | + | 2021-06-16 11:41:24.026 regex_ex2[5761:21687] Location: 7 | |
| 142 | + | 2021-06-16 11:41:24.026 regex_ex2[5761:21687] Length: 2 | |
| 143 | + | 2021-06-16 11:41:24.026 regex_ex2[5761:21687] Match: 43 | |
| 144 | + | 2021-06-16 11:41:24.026 regex_ex2[5761:21687] Range 2: {18, 2} | |
| 145 | + | 2021-06-16 11:41:24.026 regex_ex2[5761:21687] Location: 18 | |
| 146 | + | 2021-06-16 11:41:24.026 regex_ex2[5761:21687] Length: 2 | |
| 147 | + | 2021-06-16 11:41:24.026 regex_ex2[5761:21687] Match: 60 | |
| 148 | + | 2021-06-16 11:41:24.026 regex_ex2[5761:21687] Result: I have forty-three bags of sixty marbles. | |
| 149 | + | ``` | |
| 146 | 150 | ||
| 147 | 151 | ## See also | |
| 148 | 152 | ||
| 149 | 153 | - [[macOS NSRegularExpression]]. | |
| 150 | 154 | - [[RegEx packages]] - cross platform. | |
| 151 | 155 | ||
| 152 | 156 | ## External links | |
| 153 | 157 | ||
| 154 | 158 | - [Apple: NSString](https://developer.apple.com/documentation/foundation/nsstring). | |
| 155 | 159 | - [Apple: rangeOfString:options:range:](https://developer.apple.com/documentation/foundation/nsstring/1415073-rangeofstring). | |
| 156 | 160 | - [Apple: NSStringCompareOptions](https://developer.apple.com/documentation/foundation/nsstringcompareoptions). | |
| 157 | 161 | - [Apple: NSRegularExpressionSearch](https://developer.apple.com/documentation/foundation/nsstringcompareoptions/nsregularexpressionsearch). | |
| 158 | 162 | - [Apple: stringByReplacingOccurrencesOfString:withString:](https://developer.apple.com/documentation/foundation/nsstring/1412937-stringbyreplacingoccurrencesofst). | |
| 159 | 163 | ||
| 160 | 164 | --- | |
| 161 | 165 | *From the Free Pascal wiki, page "macOS NSString Regular Expressions", as it stood on 2021-08-07 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* |
