ios Swift 替换子字符串正则表达式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28503449/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 04:49:58  来源:igfitidea点击:

Swift replace substring regex

iosobjective-cregexxcodeswift

提问by jjc99

I am attempting to use regular expression to replace all occurrences of UK car registrations within a string.

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

The following swift code works perfectly for a when the string matches the regex exactly as below.

当字符串与正则表达式完全匹配时,以下 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)

The result is XX

结果是 XX

However, the following does not work and the string is not modifed

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

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)

The result is my car reg 1 - DD11 AAA my car reg 2 - AA22 BBB

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

Can anyone give me any pointers?

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

回答by DarkDust

You need to remove the ^and $anchors.

您需要删除^$锚点。

The ^means start of stringand $means end of string(or line, depending on the options). That's why your first example works: in the first test string, the start of the string is really followed by your pattern and ends with it.

^装置开始字符串$手段结束字符串(或行,这取决于选项)。这就是您的第一个示例有效的原因:在第一个测试字符串中,字符串的开头实际上是您的模式并以它结尾。

In the second test string, the pattern is found in the middle of the string, thus the ^...can't apply. If you would just remove the ^, the $would apply on the second occurrence of the registration number and the output would be my car reg 1 - DD11 AAA my car reg 2 - XX.

在第二个测试字符串中,模式位于字符串的中间,因此^...不能应用。如果您只删除^$则将应用于第二次出现的注册号,输出将为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"

回答by Ryan Brodie

Let's use a class extension to wrap this up in Swift 3 syntax:

让我们使用类扩展将其封装在 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)?")

Results in 7777777777(thus removing country code from phone number)

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

回答by Daniel J

Update for Swift 2.1:

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)
}

回答by black_pearl

Swift 4.2 Updated

斯威夫特 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)
}

回答by Martin R

With pattern: "^ ... $"you have specified that the pattern is anchored to the start and end of the string, in other words, the entirestring must match the pattern. Just remove ^and $from the pattern and you'll get the expected result.

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

回答by coyer

Warning

警告

Do not use NSRange(location: 0, length: myString.count)as all examples above quoted.

不要NSRange(location: 0, length: myString.count)像上面引用的所有例子一样使用。

Use NSRange(myString.startIndex..., in: myString)instead!

使用NSRange(myString.startIndex..., in: myString),而不是!

.countwill count newline characters like \r\nas one character - this may result in a shortened, thus invalid, NSRange that does not match the whole string.

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

(.length should work)

(.length 应该工作)