Home > Software engineering >  Swift - superscript of a String
Swift - superscript of a String

Time:10-15

I have a string of "28th and 8th. I will be working on this task". I want to super script the "th". I created a func, but this func only works fine if the last 3 letters of the first date and the second date are the different. In case they are the same, my func goes wrong

var exampletString = "28th and 8th. I will be working on this task"
var convertedAttrString = NSMutableAttributedString(string: exampletString)
func applySuperscriptAttributes(substring: String, originalString: String, convertedString: NSMutableAttributedString){
    if let subRange = originalString.range(of: substring){
        let convertedRange = NSRange(subRange, in: originalString)
        convertedString.setAttributes([.font: UIFont.systemFont(ofSize: 10, weight: .regular)], range: NSRange(location: convertedRange.location   convertedRange.length - 2, length: 2))
    }
}
applySuperscriptAttributes(substring: "28th", originalString: exampletString, convertedString: convertedAttrString)
applySuperscriptAttributes(substring: "8th", originalString: exampletString, convertedString: convertedAttrString)
// The result is "28th and 8th ..." with the "8th" not super script

CodePudding user response:

You are using the method String.range(of:). That method finds the FIRST occurrence of the substring in the target string.

The string "8th" appears as part of the first string "28th", which has already been been converted to superscripted.

You will need to write code that intelligently parses your string by words, looking for the word "8th", not a string of characters "8th" that could be in the middle of another word.

CodePudding user response:

You can use regex to solve this issue.

func applySuperscriptAttributes(substring: String, originalString: String, convertedString: NSMutableAttributedString) {
    let regex = try! NSRegularExpression(pattern: "\\d \(substring)")
    let matches = regex.matches(in: originalString, range: NSRange(location: 0, length: originalString.count))

    matches.forEach { match in
        let convertedRange = match.range
        convertedString.setAttributes([.font: UIFont.systemFont(ofSize: 10, weight: .regular)], range: NSRange(location: convertedRange.location   convertedRange.length - substring.count, length: substring.count))
    }
}

It also has support for additional 1st, 2nd, 3rd suffixes:

let st = NSMutableAttributedString(string: "The 1st stast 181st")
applySuperscriptAttributes(substring: "st", originalString: output.string, convertedString: st)
let nd = NSMutableAttributedString(string: "The 2nd ndand 181nd")
applySuperscriptAttributes(substring: "nd", originalString: output.string, convertedString: nd)
let rd = NSMutableAttributedString(string: "The 3rd rdard 181rd")
applySuperscriptAttributes(substring: "rd", originalString: output.string, convertedString: rd)
let th = NSMutableAttributedString(string: "The 4th thath 28th")
applySuperscriptAttributes(substring: "th", originalString: output.string, convertedString: th)
  • Related