3

I want to detect the words that begin with a #, and return their specific ranges. Initially I tried using the following code:

for word in words {
    if word.hasPrefix("#") {
        let matchRange = theSentence.range(of: word)
        //Do stuff with this word
    }
}

This works fine, except if you have a duplicate hashtag it will return the range of the first occurrence of the hashtag. This is because of the nature of the range(_:) function.

Say I have the following string:

"The range of #hashtag should be different to this #hashtag"

This will return (13, 8) for both hashtags, when really it should return (13, 8) as well as (50, 8). How can this be fixed? Please note that emojis should be able to be detected in the hashtag too.

EDIT

If you want to know how to do this with emojis to, go here

Community
  • 1
  • 1
Tometoyou
  • 7,792
  • 12
  • 62
  • 108
  • You should ignore the last found # and substring beyond the last found `hastag` so it will eliminate the last position, you query should be in `while(theSentence.range(of: "#")!= nil)` – iphonic Sep 26 '16 at 10:03
  • If you are going to use regular expressions then this might help: http://stackoverflow.com/a/27880748/1187415, it handles all Unicodes (Emojis, flags, ...) correctly. – Martin R Sep 26 '16 at 10:47

2 Answers2

10

Create regex for that and use it with the NSRegularExpression and find the matches range.

var str = "The range of #hashtag should be different to this #hashtag"
let regex = try NSRegularExpression(pattern: "(#[A-Za-z0-9]*)", options: [])
let matches = regex.matchesInString(str, options:[], range:NSMakeRange(0, str.characters.count))
for match in matches {
    print("match = \(match.range)")
}
Nirav D
  • 71,513
  • 12
  • 161
  • 183
0

Why don't you separate your word in chunks where each chunk starts with #. Then you can know how many times your word with # appears in sentence.

Edit: I think that regex answer is the best way for this but this is an other approach for same solution.

var hastagWords = [""]
for word in words {
    if word.hasPrefix("#") {
        // Collect all words which begin with # in an array
        hastagWords.append(word)
    }
}

// Create a copy of original word since we will change it
var mutatedWord = word.copy() as! String

for hashtagWord in hastagWords {
    let range = mutatedWord.range(of: hashtagWord)

    if let aRange = range {
        // If range is OK then remove the word from original word and go to an other range
        mutatedWord = mutatedWord.replacingCharacters(in: aRange, with: "")
    }
}
Josip B.
  • 2,434
  • 1
  • 25
  • 30