Как заменить первое появление в Swift?

Как я могу использовать replacingOccurrences с регулярным выражением и заменять только первое вхождение?

пример

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

2 ответов


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)

вы можете фактически использовать общую работу с немного измененным регулярным выражением (идея, уже предложенная @I'L'I, но я предлагаю небольшую модификацию к нему):

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

два замечания:

  • (?s)([0-9]+)(.*) - соответствует первым 1 или более цифрам (Группа 1), а затем захватывает всю остальную часть строки (обратите внимание, что . будет соответствовать разрывам линии благодаря (?s) встроенный модификатор "dotall")
  • замена часть 4 обратные косые черты для замены на 1 обратную косую черту, поэтому вам нужно поместить туда 8 обратных косых черт, чтобы получить 2 литеральные обратные косые черты в выходных данных.

похож на @CodeDifferent solution использование строки mutating .replaceSubrange метод упомянутые @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") или отрицательные lookarounds (т. е. " (?
  • поскольку регулярные выражения ICU по умолчанию известны Unicode, вы должны рассмотреть возможность использования [0-9] вместо \d чтобы избежать совпадения цифр, отличных от ASCII.