Swift替换子串正则表达式

时间:2015-02-13 15:51:54

标签: ios objective-c regex xcode swift

我正在尝试使用正则表达式来替换字符串中所有出现的英国汽车注册。

以下swift代码完全适用于字符串与正则表达式完全匹配的情况。

var myString = "DD11 AAA"
var stringlength = countElements(myString) 
var ierror: NSError?
var regex:NSRegularExpression = NSRegularExpression(pattern: "^([A-HK-PRSVWY][A-HJ-PR-Y])\\s?([0][2-9]|[1-9][0-9])\\s?[A-HJ-PR-Z]{3}$", options: NSRegularExpressionOptions.CaseInsensitive, error: &ierror)!
var modString = regex.stringByReplacingMatchesInString(myString, options: nil, range: NSMakeRange(0, stringlength), withTemplate: "XX")
print(modString)

结果为XX

但是,以下操作不起作用且字符串未修改

var myString = "my car reg 1 - DD11 AAA  my car reg 2 - AA22 BBB"
var stringlength = countElements(myString) 
var ierror: NSError?
var regex:NSRegularExpression = NSRegularExpression(pattern: "^([A-HK-PRSVWY][A-HJ-PR-Y])\\s?([0][2-9]|[1-9][0-9])\\s?[A-HJ-PR-Z]{3}$", options: NSRegularExpressionOptions.CaseInsensitive, error: &ierror)!
var modString = regex.stringByReplacingMatchesInString(myString, options: nil, range: NSMakeRange(0, stringlength), withTemplate: "XX")
print(modString)

结果为my car reg 1 - DD11 AAA my car reg 2 - AA22 BBB

任何人都可以给我任何指示吗?

6 个答案:

答案 0 :(得分:39)

您需要删除^$锚点。

^表示字符串$表示字符串结尾(或行,具体取决于选项)。这就是你的第一个例子工作的原因:在第一个测试字符串中,字符串的开头实际上是你的模式,然后以它结束。

在第二个测试字符串中,模式位于字符串的中间,因此^...无法应用。如果您只是删除^$将适用于第二次出现的注册号,输出将为my car reg 1 - DD11 AAA my car reg 2 - XX

let myString = "my car reg 1 - DD11 AAA  my car reg 2 - AA22 BBB"
let regex = try! NSRegularExpression(pattern: "([A-HK-PRSVWY][A-HJ-PR-Y])\\s?([0][2-9]|[1-9][0-9])\\s?[A-HJ-PR-Z]{3}", options: NSRegularExpression.Options.caseInsensitive)
let range = NSMakeRange(0, myString.count)
let modString = regex.stringByReplacingMatches(in: myString, options: [], range: range, withTemplate: "XX")
print(modString)
// Output: "my car reg 1 - XX  my car reg 2 - XX"

答案 1 :(得分:17)

让我们使用类扩展来用Swift 3语法包装它:

extension String {
    mutating func removingRegexMatches(pattern: String, replaceWith: String = "") {
        do {
            let regex = try NSRegularExpression(pattern: pattern, options: NSRegularExpression.Options.caseInsensitive)
            let range = NSMakeRange(0, self.count)
            self = regex.stringByReplacingMatches(in: self, options: [], range: range, withTemplate: replaceWith)
        } catch {
            return
        }
    }
}

var phoneNumber = "+1 07777777777"
phoneNumber.removingRegexMatches(pattern: "\\+\\d{1,4} (0)?")

结果7777777777(从而删除电话号码中的国家/地区代码)

答案 2 :(得分:9)

Swift 2.1更新:

var myString = "my car reg 1 - DD11 AAA  my car reg 2 - AA22 BBB"
if let regex = try? NSRegularExpression(pattern: "([A-HK-PRSVWY][A-HJ-PR-Y])\\s?([0][2-9]|[1-9][0-9])\\s?[A-HJ-PR-Z]{3}", options: .CaseInsensitive) {
    let modString = regex.stringByReplacingMatchesInString(myString, options: .WithTransparentBounds, range: NSMakeRange(0, myString.characters.count), withTemplate: "XX")
    print(modString)
}

答案 3 :(得分:4)

使用pattern: "^ ... $",您已指定模式已锚定 到字符串的开头和结尾,换句话说,整个字符串 必须匹配模式。只需从模式中删除^$即可 你会得到预期的结果。

答案 4 :(得分:1)

Swift 4.2更新

let myString = "my car reg 1 - DD11 AAA  my car reg 2 - AA22 BBB"
if let regex = try? NSRegularExpression(pattern: "([A-HK-PRSVWY][A-HJ-PR-Y])\\s?([0][2-9]|[1-9][0-9])\\s?[A-HJ-PR-Z]{3}", options: .caseInsensitive) {
    let modString = regex.stringByReplacingMatches(in: myString, options: [], range: NSRange(location: 0, length:  myString.count), withTemplate: "XX")
    print(modString)
}

答案 5 :(得分:0)

警告

请勿使用NSRange(location: 0, length: myString.count)作为以上引用的所有示例。

改为使用NSRange(myString.startIndex..., in: myString)

.count会将\r\n之类的换行符视为一个字符-这可能会导致NSRange缩短,因此无效,它与整个字符串不匹配。

(。length应该可以工作)