如何替换Swift中的第一个出现?

时间:2017-06-12 04:09:05

标签: regex swift

如何将replacementOccurrences与regex一起使用并仅替换第一次出现?

实施例

var str = "= 1 = 2 = 3"
str = str.replacingOccurrences(of: "(\\d+)", with: "\\\\$1", options: .regularExpression)
// prints: = \\1 = \\2 = \\3
// should print: = \\1 = 2 = 3

2 个答案:

答案 0 :(得分:5)

String.range()将在第一场比赛时停止:

var str = "= 1 = 2 = 3"
if let range = str.range(of: "\\d+", options: .regularExpression) {
    let substr = str[range]
    str = str.replacingCharacters(in: range, with: "\\\\" + substr)
}

print(str)

答案 1 :(得分:0)

你实际上可能会使用一些经过修改的正则表达式的常见解决方法(@I'L'I已经提出了这个想法,但我建议对它进行一些修改):

var str = "= 1 = 2 = 3"
str = str.replacingOccurrences(of: "(?s)([0-9]+)(.*)", with: "\\\\\\\\$1$2", options: .regularExpression)
print(str) // => = \\1 = 2 = 3

两个评论:

  • (?s)([0-9]+)(.*) - 匹配前1个或多个数字(组1),然后捕获字符串的所有其余部分(请注意.将匹配换行,这要归功于(?s)内联“dotall”修饰符)
  • 更换部件需要4个反斜杠替换为1个反斜杠,因此,您需要在其中放置8个反斜杠以在输出中获得2个字面反斜杠。

类似于使用@CodeDifferent solution提到的字符串变异.replaceSubrange method@MartinR

var str = "= 123 = 256 = 378"
if let range = str.range(of: "[0-9]+", options: .regularExpression) {
    str.replaceSubrange(range, with: "\\\\" + str[range])
}
print(str) // => = \\123 = 256 = 378

关于正则表达式的提示:

  • 要匹配独立号码(不是ABC1234中的那些号码),请使用字边界("\\b[0-9]+\\b")或否定外观(即“(?
  • 由于ICU regexp默认支持Unicode,因此您应该考虑使用[0-9]而不是\d来避免匹配非ASCII数字。