我有一个正则表达式,旨在从CocoaPods定义中提取git URL。
输入文本如下:
pod 'Alamofire', :git => 'https://github.com/Alamofire/Alamofire.git', :branch => 'dev'
正则表达式如下:
(?<=('Alamofire'.*:git => '))[A-Za-z:/\.]+(?=('{1}))
此正则表达式可在RegexR上正常工作,请参见here,但是,当尝试使用它初始化NSRegularExpression
时,抛出错误2048代码,表明该模式无效。通常这是由于缺乏逃生通道,但这里没有。即使拖曳了iOS使用的引擎ICU regex文档,我也无法解决问题所在。
任何想法都会受到欢迎,TIA。
答案 0 :(得分:0)
NSRegularExpression
中的后向声明是有限的,并且不支持其中的*
或+
运算符:
即.*
中的(?<=('Alamofire'.*:git => '))
部分
(?<= ...)
后置断言。如果带括号的模式与文本匹配,则为真 在当前输入位置之前,最后一个字符 match是当前位置之前的输入字符。是否 不改变输入位置。可能匹配的字符串的长度 后向模式所构成的对象不能无界(没有*或+ 运算符。)
参考:https://developer.apple.com/documentation/foundation/nsregularexpression
您只希望url如此简单地仅匹配该部分,而无需首先使用后置断言。
答案 1 :(得分:0)
在带有ICU正则表达式的后向模式中不能使用长度未知的模式。您的模式在后向中包含.*
,因此它是无效的ICU regexp(请参阅与后向模式匹配的可能字符串的长度不能无限(无*
或+
运算符。) ICU向后看文档部分)。
有两种方法:
.*
替换为.{0,x}
,其中x
是您希望将左侧模式与右侧模式分开的最大字符数,ICU regex后面允许 limiting (或 interval , range )量词,这就是为什么它们也被称为“约束宽度”的原因这里是方法2,建议:
let str = "pod 'Alamofire', :git => 'https://github.com/Alamofire/Alamofire.git', :branch => 'dev'"
let rng = NSRange(location: 0, length: str.utf16.count)
let regex = try! NSRegularExpression(pattern: "'Alamofire'.*:git\\s*=>\\s*'([^']+)'")
let matches = regex.matches(in: str, options: [], range: rng)
let group1 = String(str[Range(matches[0].range(at: 1), in: str)!])
print(group1) // => https://github.com/Alamofire/Alamofire.git
请参见regex demo,绿色突出显示的子字符串是您在第1组中获得的值。
模式详细信息:
'Alamofire'
-文字字符串.*
-尽可能多的除换行符以外的0+字符(用.*?
替换以尽可能少地匹配):git
-文字子字符串\s*=>\s*
-一个=>
子字符串,其中包含0+空格'([^']+)'
-'
,然后是捕获组#1,其匹配除'
以外的1个以上的字符,然后匹配一个'
字符。