Swift正则表达式:一个字符串是否匹配一个模式?

48

在Swift中,判断一个字符串是否匹配某个模式的简单方法是什么?

伪代码示例:

if string matches pattern ...

if string =~ pattern ...

我已经阅读了Swift文档,但没有看到正则表达式的功能。我已经了解到可以添加一个新的=~操作符,这是一个不错的想法,但比我想要的更复杂了,因为这是一个教学项目。我尝试使用rangeOfString,但出现错误:'String' does not have a member 'rangeOfString'。我正在寻找Swift解决方案,即不需要输入NSRegularExpression。我不需要对匹配结果数据执行任何操作。


可能是Swift正则表达式匹配的重复问题。 - picciano
@picciano 感谢提供链接 - 我已经添加了一个澄清,说明这个问题与链接的问题不同,因为我只想使用Swift术语,而不是NSRegularExpression。 - joelparkerhenderson
4个回答

80

Swift 3 版本的解决方案:

if string.range(of: regex, options: .regularExpression, range: nil, locale: nil) != nil ...

Swift 2 解决方案:

if string.rangeOfString(pattern, options: .RegularExpressionSearch) != nil ...

示例——这个字符串包含两个字母“o”吗?

"hello world".rangeOfString("o.*o", options: .RegularExpressionSearch) != nil
注意:如果您收到错误消息'String' does not have a member 'rangeOfString',则在此之前添加以下内容:import Foundation。这是因为Foundation提供了自动桥接到Swift String类的NSString方法。
import Foundation

感谢 Onno Eberhard 进行 Swift 3 的更新。


1
为什么不使用regex.firstMatch(in: string, options: [], range: NSRange(location: 0, length: string.count)) != nil呢?这难道不比range(of:options:range:locale:)更语义化清晰吗? - Iulian Onofrei

53

上面提到的解决方案对我不再起作用了,所以我在这里发布我的解决方案(我使用了一个字符串扩展):

extension String {
    func matches(_ regex: String) -> Bool {
        return self.range(of: regex, options: .regularExpression, range: nil, locale: nil) != nil
    }
}

例子:

if str.matches("^[a-zA-Z0-9._-]{1,30}$") {
    //...
}

2
请查看正则表达式的参考资料、示例和实时演示:http://regexr.com - naeemjawaid
你节省了我的4个小时。可重用的方法非常有帮助。 - Karthick Ramesh

15
为了获得您实际需要的语法,您可以轻松地定义一个新操作符,该操作符包装了桥接的NSString功能:

要获取您实际询问的语法,您可以轻松定义一个新运算符,该运算符包装了桥接的NSString功能:

infix operator =~ {}
func =~(string:String, regex:String) -> Bool {
    return string.rangeOfString(regex, options: .RegularExpressionSearch) != nil
}

"abcd" =~ "ab*cd"
"abcd" =~ "abcde+"

谢谢David。对于这个特定的项目,我正在寻找一种不定义新运算符的解决方案。(如果Swift将您的想法添加到整个语言中,那将是很棒的,依我之见) - joelparkerhenderson

-1
在Swift 4.2中,即使字符串不匹配模式,以下内容也不会返回nil:
string.range(of: regex, options: .regularExpression, range: nil, locale: nil)

正如 Xcode 建议:

比较类型为 'NSRange'(又名 '_NSRange')的非可选值与 nil 的结果始终为 true

因此我最终使用的是:

if string.range(of: regex, options: .regularExpression)
        .location != NSNotFound {
    // do stuff if string matches regexp
}

1
你正在调用 NSString 上的方法,而不是 String,这就是你的问题所在。你的解决方案对于 NSString 在技术上是正确的,但你也可以只需执行 (string as String).range(of: ...) != nil - Sulthan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接