@@ -1130,7 +1130,7 @@ extension NSString {
1130
1130
}
1131
1131
return " "
1132
1132
}
1133
-
1133
+
1134
1134
open func replacingOccurrences( of target: String , with replacement: String , options: CompareOptions = [ ] , range searchRange: NSRange ) -> String {
1135
1135
if options. contains ( . regularExpression) {
1136
1136
return _stringByReplacingOccurrencesOfRegularExpressionPattern ( target, withTemplate: replacement, options: options, range: searchRange)
@@ -1462,19 +1462,38 @@ extension NSMutableString {
1462
1462
if options. contains ( . regularExpression) {
1463
1463
return _replaceOccurrencesOfRegularExpressionPattern ( target, withTemplate: replacement, options: options, range: searchRange)
1464
1464
}
1465
-
1466
1465
1467
- if let findResults = CFStringCreateArrayWithFindResults ( kCFAllocatorSystemDefault, _cfObject, target. _cfObject, CFRange ( searchRange) , options. _cfValue ( true ) ) {
1468
- let numOccurrences = CFArrayGetCount ( findResults)
1466
+ guard let findResults = CFStringCreateArrayWithFindResults ( kCFAllocatorSystemDefault, _cfObject, target. _cfObject, CFRange ( searchRange) , options. _cfValue ( true ) ) else {
1467
+ return 0
1468
+ }
1469
+ let numOccurrences = CFArrayGetCount ( findResults)
1470
+
1471
+ return withExtendedLifetime ( findResults) {
1472
+ guard type ( of: self ) == NSMutableString . self else {
1473
+ // If we're dealing with non NSMutableString, mutations must go through `replaceCharacters` (documented behavior)
1474
+ for cnt in 0 ..< numOccurrences {
1475
+ let rangePtr = CFArrayGetValueAtIndex ( findResults, backwards ? cnt : numOccurrences - cnt - 1 )
1476
+ replaceCharacters ( in: NSRange ( rangePtr!. load ( as: CFRange . self) ) , with: replacement)
1477
+ }
1478
+
1479
+ return numOccurrences
1480
+ }
1481
+
1482
+ var newStorage = Substring ( )
1483
+ var sourceStringCurrentIndex = _storage. startIndex
1469
1484
for cnt in 0 ..< numOccurrences {
1470
- let rangePtr = CFArrayGetValueAtIndex ( findResults, backwards ? cnt : numOccurrences - cnt - 1 )
1471
- replaceCharacters ( in: NSRange ( rangePtr!. load ( as: CFRange . self) ) , with: replacement)
1485
+ let rangePtr = CFArrayGetValueAtIndex ( findResults, backwards ? numOccurrences - cnt - 1 : cnt)
1486
+ let range = NSRange ( rangePtr!. load ( as: CFRange . self) )
1487
+ let matchStartIndex = String . Index ( utf16Offset: range. location, in: _storage)
1488
+ let matchEndIndex = String . Index ( utf16Offset: range. location + range. length, in: _storage)
1489
+ newStorage += _storage [ sourceStringCurrentIndex..< matchStartIndex]
1490
+ newStorage += replacement
1491
+ sourceStringCurrentIndex = matchEndIndex
1472
1492
}
1493
+ newStorage += _storage [ sourceStringCurrentIndex ..< _storage. endIndex]
1494
+ _storage = String ( newStorage)
1473
1495
return numOccurrences
1474
- } else {
1475
- return 0
1476
1496
}
1477
-
1478
1497
}
1479
1498
1480
1499
public func applyTransform( _ transform: String , reverse: Bool , range: NSRange , updatedRange resultingRange: NSRangePointer ? ) -> Bool {
0 commit comments