Регулярное выражение для указанного c количества специальных символов в Swift - PullRequest
0 голосов
/ 21 февраля 2020

У меня есть строка типа

start tcp connect
1\'s time=46ms, 2\'s time=14ms, 3\'s time=10ms, 4\'s time=24ms, 5\'s time=10ms, average=20ms
start tcp connect end
ping: XXX.XXX.com start
64 bytes from 111.111.111.111 icmp_seq=#0 type=ICMPv4TypeEchoReply time=10ms
64 bytes from 111.111.111.111 icmp_seq=#1 type=ICMPv4TypeEchoReply time=10ms
64 bytes from 111.111.111.111 icmp_seq=#2 type=ICMPv4TypeEchoReply time=34ms
ping: XXX.XXX.com end

Я хочу получить миллисекунду из этой строки Этот результат типа [10,10,34]

Я пытаюсь использовать

64 байта из \ d +. \ D +. \ D +. \ D + icmp_seq = # \ d + type = ICMPv4TypeEchoReply time = (\ d +) мс

, но получить весь массив строк [" 64 байта из 122.51.224.87 icmp_seq = # 0 type = ICMPv4TypeEchoReply time = 10ms ", ....]

Ответы [ 3 ]

0 голосов
/ 21 февраля 2020

Вы можете создать шаблон, чтобы найти любое количество цифр \d+ между двумя строками, используя оглядку (?<=) и заглядывая в будущее (?=), создавая регулярное выражение, например (?<=64 bytes from \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} icmp_seq=#\d{1} type=ICMPv4TypeEchoReply time=)\d+(?=ms), и ищите вашу строку, пока вы находите совпадение:

func getTimes(from string: String) -> [Int] {
    let pattern = #"(?<=64 bytes from \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} icmp_seq=#\d{1} type=ICMPv4TypeEchoReply time=)\d+(?=ms)"#
    var times: [Int] = []
    var startIndex = string.startIndex
    while let range = string[startIndex...].range(of: pattern, options: .regularExpression) {
        times.append(Int(string[range])!)
        startIndex = range.upperBound
    }
    return times
}

Тестирование игровой площадки:

let string = """
start tcp connect
1\'s time=46ms, 2\'s time=14ms, 3\'s time=10ms, 4\'s time=24ms, 5\'s time=10ms, average=20ms
start tcp connect end
ping: XXX.XXX.com start
64 bytes from 111.111.111.111 icmp_seq=#0 type=ICMPv4TypeEchoReply time=10ms
64 bytes from 111.111.111.111 icmp_seq=#1 type=ICMPv4TypeEchoReply time=10ms
64 bytes from 111.111.111.111 icmp_seq=#2 type=ICMPv4TypeEchoReply time=34ms
ping: XXX.XXX.com end
"""

let times = getTimes(from: string)
print(times)  // "[10, 10, 34]\n"
0 голосов
/ 21 февраля 2020

Вы можете использовать группу захвата для цифр. Таким образом:

let results = try! NSRegularExpression(pattern: #"Reply time=(\d+)ms"#)
    .matches(in: string, range: NSRange(string.startIndex..., in: string))
    .compactMap { $0.range(at: 1) }
    .compactMap { Range($0, in: string) }
    .compactMap { Int(string[$0]) }

Теперь я использую \d+, чтобы сопоставить любую последовательность из одной или нескольких цифр. Но если вы хотите сопоставить определенное количество цифр, скажем, от одной до трех цифр, вы можете использовать \d{1,3}. Но в этом случае я не уверен, почему вы хотите ограничить его указанным c числом цифр (например, действительно ли вы хотите исключить числа, превышающие 999?). Но { и } с минимальным и максимальным числом вхождений - это то, как вы указали бы количество цифр.

0 голосов
/ 21 февраля 2020

Если all - это строка, содержащая весь текст, который вы показываете, это будет работать:

let values = all
    .split(separator: "\n")
    .filter { $0.hasPrefix("64 bytes from") }
    .map { (substring: Substring) -> Substring in
        let start = substring.range(of: "time=")!
        let end = substring.range(of: "ms")!
        return substring[start.upperBound..<end.lowerBound]
    }
    .map { Int($0)! }

values будет тогда массивом целых чисел: [10, 10, 34].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...