Search code examples
iosswiftregexmacosnsregularexpression

Regular expression not working in iOS, works fine elsewhere


I have a regular expression to parse pod names from the CocoaPods podfile; I wrote this to be used as part of a vulnerability scan.

This RegEx can be seen to be working in RegexR, as can be seen here. However, when used in NSRegularExpression, no matches are returned from the same input.

I have known NSRegularExpression to be a bit finicky before but I can't work out the problem on this occasion.

The regex is: /(?<=pod ')[A-Za-z/]+(?=')/g

My Swift code is:

guard let podNameRegex = try? NSRegularExpression(pattern: "/(?<=pod ')[A-Za-z/]+(?=')/g", options: [.useUnicodeWordBoundaries]) else {
    fputs("Failed to instantiate pod name regex.", stderr)
    throw NSError()
}

let podfilePodNameMatches = podNameRegex.matches(in: podfileString, options: [], range: NSRangeFromString(podfileString))
let matchStrings = podfilePodNameMatches.map({ (podfileString as NSString).substring(with: $0.range) })

However, no matches are returned.

Does anyone know where the issue lies? TIA


Solution

  • You don't need to use the /{pattern}/g syntax in Swift.

    This worked for me in a playground

    import UIKit
    import PlaygroundSupport
    
    let podfileString = """
    platform :ios, '11.0'
    
    inhibit_all_warnings!
    use_frameworks!
    use_modular_headers!
    
    def shared_pods
        pod 'CocoaLumberjack/Swift'
        pod 'PromiseKit'
        pod 'GZIP'
        pod 'Eureka' => '4.2.0', :configuration => 'Debug'
        pod 'RATreeView'
        pod 'LicensesViewController'
    end
    
    target 'DigiMe' do
        pod 'Masonry'
        pod 'Instabug'
        pod 'SAMKeychain'
        pod 'Mixpanel'
        pod 'SDWebImage'
        pod 'FLAnimatedImage'
        pod 'SnapKit', '~> 4.0.0'
        pod 'ObjectMapper'
        pod 'SwiftLint'
        pod 'MarqueeLabel/Swift'
        pod 'Alamofire'
        pod 'PromiseKit/Alamofire'
        pod 'UIColor_Hex_Swift'
        pod 'SwiftyJSON'
        pod 'Hero'
        pod 'GPUImage'
        shared_pods
    end
    
    target 'DigiMeTests' do
    
        ####### SPECTA ######
        pod 'Specta',       '~> 1.0'
        pod 'Expecta',      '~> 1.0'   # expecta matchers
        pod 'OHHTTPStubs/Swift'
        #####################
    
        shared_pods
    end
    
    post_install do |installer|
        installer.pods_project.targets.each do |target|
            target.build_configurations.each do |config|
                preprocessor_definitions = config.build_settings['GCC_PREPROCESSOR_DEFINITIONS']
                preprocessor_definitions = ['$(inherited)'] if preprocessor_definitions == nil
                preprocessor_definitions.push 'MIXPANEL_NO_IFA' if target.to_s.include? 'Mixpanel'
                config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = preprocessor_definitions
                config.build_settings['CLANG_ENABLE_CODE_COVERAGE'] = 'NO'
            end
        end
    end
    """
    
    let range = NSRange(location: 0, length: podfileString.utf16.count)
    let regex = try! NSRegularExpression(pattern: "(?<=pod ')[A-Za-z/]+(?=')")
    let matches = regex.matches(in: podfileString, options: [], range: range)
    let matchStrings = matches.map({ (podfileString as NSString).substring(with: $0.range) })
    print(matchStrings)
    

    Output:

    ["CocoaLumberjack/Swift", "PromiseKit", "GZIP", "Eureka", "RATreeView", "LicensesViewController", "Masonry", "Instabug", "SAMKeychain", "Mixpanel", "SDWebImage", "FLAnimatedImage", "SnapKit", "ObjectMapper", "SwiftLint", "MarqueeLabel/Swift", "Alamofire", "PromiseKit/Alamofire", "SwiftyJSON", "Hero", "GPUImage", "Specta", "Expecta", "OHHTTPStubs/Swift"]