Сопоставление и замена шаблона регулярных выражений в Swift - PullRequest
0 голосов
/ 03 апреля 2020

У меня есть следующие строки:

Hi this is %1$s, product %2$s Hi this is %2$s, product %2$s

Я хочу заменить %1$s на {0} и %2$s на {1} и так далее ..

Я пытался сделать:

let range = NSRange(location: 0, length: myString.count)
var regex = try! NSRegularExpression(pattern: "%[1-9]\\$s", options: [])
var newStr = regex.stringByReplacingMatches(in: myString, options: [], range: range, withTemplate: "XXXX")

Любой может помочь мне, пожалуйста!

1 Ответ

0 голосов
/ 03 апреля 2020

Ваш шаблон неправильный, у вас в начале [a-z], поэтому вы ничего не обнаруживаете.

Кроме того, предпочитает считать utf16 с NSStuff (потому что с NSString это UTF16)

let myString = "Hi this is %1$s, product %2$s Hi this is %2$s, product %2$s"

let range = NSRange(location: 0, length: myString.utf16.count)
var regex = try! NSRegularExpression(pattern: "%(\\d+)\\$s", options: [])
var newStr = regex.stringByReplacingMatches(in: myString, options: [], range: range, withTemplate: "{$1}")
print(newStr)

Вывод:

$>Hi this is {1}, product {2} Hi this is {2}, product {2}

Некоторое объяснение %(\d+)\$s (а затем повторить \ для строк Swift).
%: Определить "%"
\d+: обнаружение номера (включая 12, которое раньше не было в вашем случае)
(\d+): обнаружение номера, но в группе захвата
\$: обнаружение «$» (нужен побег, потому что это специальный char в регулярном выражении)
s: определение "s"

Таким образом, есть две группы: целое (соответствующее всему совпадению регулярного выражения) и числа. Первый из них будет $ 0, а второй $ 1, поэтому я использовал {$1} в шаблоне.

Примечание: я использовал https://regex101.com для проверки шаблона.

С увеличением вы не можете сделать это с шаблоном. Вы должны перечислить все совпадения, выполнить операцию и заменить.

var myString = "Hi this is %1$s, product %2$s Hi this is %2$s, product %2$s"
let range = NSRange(location: 0, length: myString.utf16.count)
var regex = try! NSRegularExpression(pattern: "%(\\d+)\\$s", options: [])
let matches = regex.matches(in: myString, options: [] , range: range)
matches.reversed().forEach({ aMatch in
    let fullNSRange = aMatch.range
    guard let fullRange = Range(fullNSRange, in: myString) else { return }
    let subNSRange = aMatch.range(at: 1)
    guard let subRange = Range(subNSRange, in: myString) else { return }
    let subString = myString[subRange]
    guard let subInt = Int(subString) else { return }
    let replacement = "{" + String(subInt + 1) + "}"
    myString.replaceSubrange(fullRange, with: replacement)
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...