简体   繁体   中英

Swift 4 Replace word within String

The setup: A UITextField and a Tableview with suggested users I try to have the following result:

I want users to be able to link other users. Its working fine as long as I search with my last word in the array

 let caption = captionTextView.text
    let words = caption?.components(separatedBy: .whitespacesAndNewlines)

     guard let searchingWord = words?.last else {return}

    if searchingWord.hasPrefix("@") {
        self.indicator.startAnimating()
        let search = searchingWord.trimmingCharacters(in: CharacterSet.punctuationCharacters).lowercased()
 }

But in case a user wants to adjust a username in the middle or at least not at the end of the array, the searching functions doesn't work properly as it still searches with the last word in the array

Example:

"Hey how are you @Lisa @Marcel @Thomas"

In case a user wants to change "@Lisa" to "@Lisbeth" the search function will search with Thomas as its the last word in the array

I wasn't able to get the word I am working at, only last and first words in the array, however I am able to get the current cursor location with

let cursor =  captionTextView.cursorOffset!

which is an extension.

So how do I get the word I am working at up until the next "@" to the left und the next blank space to the right? Thanks in advance!

Maybe try something like this:

if let selectedRange = textview.selectedTextRange {
    let cursorOffset = textview.offset(from: textview.beginningOfDocument, to: selectedRange.start)
    let text = textview.text
    let substring = text?.prefix(cursorOffset)
    let editedWord = substring?.split(separator: "@")
}

(written on a phone, and untested)

One solution is Regular Expression

let string = "Hey how are you @Lisa @Marcel @Thomas"
let searchingWord = "Lisa"
let replacingWord = "Lisbeth"

let pattern = "@\(searchingWord)\\s"
string.replacingOccurrences(of: pattern, with: "@\(replacingWord) ", options: .regularExpression)

The pattern searches for @ followed by the searching word followed by a whitespace character.

Since you say things are working the way you want if the last word is the one that has a username in it you just need to loop over all the words. Depending on your needs you may need to keep track of the usernames that were in the text before to save you from searching for the same user multiple times, but an array of used usernames should sort that for you.

Also, unless you want to prevent users from having underscores and the such in their names you should tweak the way in which you remove the @ symbol as well.

guard let words = captionTextView.text?.components(separatedBy: .whitespacesAndNewlines) else { return }
for word in words where word.hasPrefix("@") {
    self.indicator.startAnimating()
    let search = word.replacingOccurrences(of: "@", with: "").lowercased()
}

Sticking the above code into a playground that uses the sample string you supplied in place of captionTextView.text? and printing search each time yielded…

lisa
marcel
thomas

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM