2

I want to match a string with a regex in Swift. I am following the approach described here.

Typically this would work like this (as evaluated in a Xcode playground):

var str1 = "hello"
var str2 = "bye"
var regex1 = "[abc]"
str1.rangeOfString(regex1, options:.RegularExpressionSearch) != nil // false - there is no match
str2.rangeOfString(regex1, options:.RegularExpressionSearch) != nil // true - there is a match

So far so good. Now let us take two strings which contain characters consisting of more than one Unicode scalar like so (as evaluated in a Xcode playground):

var str3 = "✔️"
var regex2 = "[✖️]"
"✔️" == "✖️" // false - the strings are not equal
str3.rangeOfString(regex2, options:.RegularExpressionSearch) != nil // true - there is a match!

I wouldn't expect a match when I try to find "✖️" in "✔️", but because "\u{2714}"+"\u{FE0F}" == "✔️" and "\u{2716}"+"\u{FE0F}" == "✖️", then "\u{FE0F}" is found in both and that gives a match.

How would you perform the match?

Community
  • 1
  • 1
atineoSE
  • 3,597
  • 4
  • 27
  • 31
  • how can `"✔️" == "✖️"` gives you false? is it typo? – William Kinaan Oct 23 '15 at 12:37
  • Have a look at https://developer.apple.com/swift/blog/?id=30 - it specifically states: "String determines equality based on being canonically equivalent. Characters are canonically equivalent if they have the same linguistic meaning and appearance, even if they are composed from different Unicode scalars behind the scenes." – Grimxn Oct 23 '15 at 12:40
  • Can't replicate your result. `str3` doesn't match `regex2`. SwiftStub: http://swiftstub.com/412516148/?v=beta – Code Different Oct 23 '15 at 19:43
  • 1
    @atineoSE: I have come across [this piece of code](https://gist.github.com/mattt/2099ee21bbfbebaa94a3#file-regex-swift). I wonder if that will fix the issue. – Wiktor Stribiżew Oct 26 '15 at 12:21
  • @WilliamKinaan I was using this code directly on a Xcode playground, that is why you get `false`, because it evaluates each expression and displays the result. That is nevertheless not the point of the question but rather the string matching. – atineoSE Oct 26 '15 at 20:23
  • @Grimxn here I am not checking for equality but for matching in a regex fashion. – atineoSE Oct 26 '15 at 20:24
  • @ZoffDino Thanks for trying and for pasting your test. Watch out though, as you seem to be using a somewhat different `✖`, that is why you can't reproduce. If you cut and paste the text in the question in a Xcode playground, you will be able to reproduce. – atineoSE Oct 26 '15 at 20:25
  • @stribizhev that set on me on a working solution, thx! – atineoSE Oct 26 '15 at 21:26

1 Answers1

1

Digging into the link provided by @stribizhev I have come up with this (as evaluated in Xcode playground):

var str1 = "hello"
var str2 = "bye"
var str3 = "✔️"
var regex1 = "[abc]"
var regex2 = "[✖️]"

let matcher1 = try! NSRegularExpression(pattern: regex1, options: NSRegularExpressionOptions.CaseInsensitive)
let matcher2 = try! NSRegularExpression(pattern: regex2, options: NSRegularExpressionOptions.CaseInsensitive)

matcher1.numberOfMatchesInString(str1, options: NSMatchingOptions.ReportCompletion, range: NSMakeRange(0, str1.characters.count)) != 0 // false - does not match
matcher1.numberOfMatchesInString(str2, options: NSMatchingOptions.ReportCompletion, range: NSMakeRange(0, str2.characters.count)) != 0 // true - matches
matcher2.numberOfMatchesInString(str3, options: NSMatchingOptions.ReportCompletion, range: NSMakeRange(0, str3.characters.count)) != 0 // false - does not match

This is for XCode 7.1 and Swift 2.1

atineoSE
  • 3,597
  • 4
  • 27
  • 31