How can we split a string according to a specific range and put the sliced items in arrays like the example below:
let sentence = "Str1 {M} Str2 {/M} Str3 {M} Str4 {/M} {M} Str5 {/M} Str6 {M} Str7 {/M}"
Note: Str1 , Str2 ... are a strings
What I want: (1,2,3 and 4)
1) OutputBetweenM = [Str2, Str4, Str5, Str7]
2) OutputOutsideM = [Str1, Str3, Str6]
3) OutputBetweenM_Edited = [Str2Edited, Str4Edited, Str5Edited, Str7Edited]
4) Output3 = [Str1, Str2Edited, Str3, Str4Edited, Str5Edited, Str6, Str7Edited]
and finally rewrite the new sentence by adding the new items in Output3 together (easy to me) to get this:
let Final_sentence = "Str1 {M} Str2Edited {/M} Str3 {M} Str4Edited {/M} {M} Str5Edited {/M} Str6 {M} Str7Edited {/M}"
That is what I try to do:
1st code:
let from = NSRegularExpression.escapedPattern(for: "{M}") // escapedPattern
let to = NSRegularExpression.escapedPattern(for: "{/M}")
let regex = "(?<=\(from))(.*?)(?=\(to))"
let ranges = sentence.ranges(of: regex, options: .regularExpression)
let matches = ranges.map{ sentence[$0] }
print(matches) /* OutputBetweenM: [" Str2 ", " Str4 ", " Str5 ", " Str7 "] ( Correct ) */
2nd Code:
let from = NSRegularExpression.escapedPattern(for: "{M}") // escapedPattern
let to = NSRegularExpression.escapedPattern(for: "{/M}")
let regexIncluding = from + ".*?" + to
let rangesIncluding = sentence.ranges(of: regexIncluding, options: .regularExpression)
var mutableSentence = sentence
print(mutableSentence)
for range in rangesIncluding.reversed() {
mutableSentence.replaceSubrange(range, with: "\n")
}
let excludedOnes = mutableSentence.components(separatedBy: .newlines)
print(excludedOnes) /* OutputOutsideM: ["Str1 ", " Str3 ", " ", " Str6 ", ""] ( InCorrect :/)
Correct one : ["Str1 ", " Str3 ", " Str6 "] */
Extension used: from a post in this page : Index of a substring in a string with Swift
func ranges(of string: String, options: CompareOptions = .literal) -> [Range<Index>] {
var result: [Range<Index>] = []
var start = startIndex
while let range = range(of: string, options: options, range: start..<endIndex) {
result.append(range)
start = range.lowerBound < range.upperBound ? range.upperBound : index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex
}
return result
}
And after that , I don't know how I can put them like Output3 , thx to @leo-dabus for his help.
Thanks in advance!