2

I found two useful javascript regex but none of them seems to be working right on Swift.

This works with a Youtube URL, but doesn't with Vimeo and DailyMotion. Both Vimeo & Dailymotion regex works on javascript.

Thanks guys.

** EDIT WITH THE SOLUTION **

Thanks GreatBigBore and Larme

private func getVendorId(_ regexStr:String, _ videoUrl:String, _ search:[Int]) -> String {

    let regex = try? NSRegularExpression(pattern: regexStr, options: .caseInsensitive)
    let result:[NSTextCheckingResult] = (regex?.matches(in: videoUrl, options: [], range: NSRange(location: 0, length: (videoUrl.characters.count ))))!

    if result.count > 0 {
        let groups = result.first!;
        for i in search {
            if (groups.rangeAt(i).length != 0) {
                return (videoUrl as NSString).substring(with: groups.rangeAt(i))
            }
        }
    }

    return "";
}

override func viewDidLoad() {

    let youtubeUrl   = "https://www.youtube.com/watch?v=MCc0V5bgEF8";
    let youtubeRegex = "((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)";
    let youtubeId    = getVendorId(youtubeRegex, youtubeUrl, [0]);
    print("YOUTUBE ID -> \(youtubeId)")

    let vimeoUrl    = "https://player.vimeo.com/video/233459603";
    let vimeoRegex  = "https?:\\/\\/(?:www\\.|player\\.)?vimeo.com\\/(?:channels\\/(?:\\w+\\/)?|groups\\/([^\\/]*)\\/videos\\/|album\\/(\\d+)\\/video\\/|video\\/|)(\\d+)(?:$|\\/|\\?)";
    let vimeoId     = getVendorId(vimeoRegex, vimeoUrl, [2]);
    print("VIMEO ID -> \(vimeoId)")

    let dailyMotionUrl   = "http://www.dailymotion.com/hub/x9q_Galatasaray";
    let dailyMotionRegex = "^.+dailymotion.com\\/(video|hub)\\/([^_]+)[^#]*(#video=([^_&]+))?";
    let dailyMotionId    = getVendorId(dailyMotionRegex, dailyMotionUrl, [4, 2]);
    print("DAILYMOTION ID -> \(dailyMotionId)")


    super.viewDidLoad()

}
noisedan
  • 170
  • 2
  • 11
  • `let regRes:[Any]` if you write `let regRes:[NSTextCheckingResult]` instead, you could avoid the `as? NSTextCheckingResult` in `regRes.first as? NSTextCheckingResult`. For the rest, did you checked all the `regRes` values instead of only first? What do they print? Since you have various regex group, it may be interesting to find which one is usefull for each regex. – Larme Sep 17 '17 at 12:27

1 Answers1

0

Your regexes are working fine. The problem is that you're not accounting for multiple capture groups. Your variable result will contain an NSRange for every capture group; you need to get your captured ID from one of those, not from result?.range. Here's some example code to show you what I mean. Add it to your getId() function, after let result:

print("Capture group count", result!.numberOfRanges)

for i in 0 ..< result!.numberOfRanges {
    if result!.range(at: i).length == 0 {
        print("Group \(i) is empty")
    } else {
        print("Group \(i) captured", (url as NSString).substring(with: result!.range(at: i)))
    }
}

It's not clear to me why your youtube id captured the way it did; I think it had something to do with all that look-behind (I'm not an expert with look-behind). But the problem is not with your regex; it's just that you need to get your id from the capture group, not directly from regRes.first.

SaganRitual
  • 3,143
  • 2
  • 24
  • 40