-2

I have a Swift based iOS app and one of the features allows you to comment on a post. Anyway, users can add "@mentions" in their posts to tag other people. However I want to stop the user from adding a username with a capital letter.

Is there anyway I can convert a string, so that the @usernames are all in lowercase?

For example:

I really enjoy sightseeing with @uSerABC (not allowed)

I really enjoy sightseeing with @userabc (allowed)

I know there is a property for the string in swift called .lowercaseString - but the problem with that, is that it makes the entire string lowercase and thats not what I want. I only want the @username to be in lower case.

Is there any way around this with having to use the .lowercase property.

Thanks for your time, Dan.

Supertecnoboff
  • 6,406
  • 11
  • 57
  • 98
  • You can use a `NSRegularExpression` to find the `@zzz` (there are a few questions on SO), and replace with the lower case for each matches (according to range) – Larme Feb 23 '16 at 09:54

3 Answers3

1

This comes from a code I use to detect hashtags, I've modified to detect mentions:

func detectMentionsInText(text: String) -> [NSRange]? {
        let mentionsDetector = try? NSRegularExpression(pattern: "@(\\w+)", options: NSRegularExpressionOptions.CaseInsensitive)
        let results = mentionsDetector?.matchesInString(text, options: NSMatchingOptions.WithoutAnchoringBounds, range: NSMakeRange(0, text.utf16.count)).map { $0 }
        return results?.map{$0.rangeAtIndex(0)}
    }

It detects all the mentions in a string by using a regex and returns an NSRange array, by using a range you have the beginning and the end of the "mention" and you can easily replace them with a lower case version.

Andrea
  • 26,120
  • 10
  • 85
  • 131
0

Split the string into two using the following command -

let arr = myString.componentsSeparatedByString("@")
//Convert arr[1] to lower case  
//Append to arr[0]
//Enjoy
Abhishek729
  • 327
  • 5
  • 14
  • 1
    May I know the reason for downvoting my solution because if there are any flaws in the solution i provided, then I can try for a better solution and learn something new in the process – Abhishek729 Feb 23 '16 at 17:42
0

Thanks to everyone for their help. In the end I couldn't get any of the solutions to work and after a lot of testing, I came up with this solution:

func correctStringWithUsernames(inputString: String, completion: (correctString: String) -> Void) {

            // Create the final string and get all
            // the seperate strings from the data.
            var finalString: String!
            var commentSegments: NSArray!
            commentSegments = inputString.componentsSeparatedByString(" ")

            if (commentSegments.count > 0) {

                for (var loop = 0; loop < commentSegments.count; loop++) {

                    // Check the username to ensure that there
                    // are no capital letters in the string.
                    let currentString = commentSegments[loop] as! String
                    let capitalLetterRegEx  = ".*[A-Z]+.*"
                    let textData = NSPredicate(format:"SELF MATCHES %@", capitalLetterRegEx)
                    let capitalResult = textData.evaluateWithObject(currentString)

                    // Check if the current loop string
                    // is a @user mention string or not.

                    if (currentString.containsString("@")) {

                        // If we are in the first loop then set the
                        // string otherwise concatenate the string.

                        if (loop == 0) {

                            if (capitalResult == true) {

                                // The username contains capital letters
                                // so change it to a lower case version.
                                finalString = currentString.lowercaseString
                            }

                            else {

                                // The username does not contain capital letters.
                                finalString = currentString
                            }
                        }

                        else {

                            if (capitalResult == true) {

                                // The username contains capital letters
                                // so change it to a lower case version.
                                finalString = "\(finalString) \(currentString.lowercaseString)"
                            }

                            else {

                                // The username does not contain capital letters.
                                finalString = "\(finalString) \(currentString)"
                            }
                        }
                    }

                    else {

                        // The current string is NOT a @user mention
                        // so simply set or concatenate the finalString.

                        if (loop == 0) {
                            finalString = currentString
                        }

                        else {
                            finalString = "\(finalString) \(currentString)"
                        }
                    }
                }
            }

            else {

                // No issues pass back the string.
                finalString = inputString
            }

            // Pass back the correct username string.
            completion(correctString: finalString)       
}

Its certainly not the most elegant or efficient solution around but it does work. If there are any ways of improving it, please leave a comment.

Supertecnoboff
  • 6,406
  • 11
  • 57
  • 98