Как я могу найти совпадение с регулярным выражением, которое начинается перед определенным индексом строки? - PullRequest
0 голосов
/ 25 февраля 2019

Допустим, у меня есть регулярное выражение

let regexString = "\\s{1,3}(---+)\\s*"
let regex = try? NSRegularExpression(pattern: regexString)

и строка

let string = "Space --- the final frontier --- these are the voyages..."

, и давайте далее предположим, что строка была действительно длинной и продолжалась послеэллипсы (...) для нескольких тысяч символов.

Теперь я хочу найти первое совпадение для регулярного выражения regex, но я хочу прекратить поиск после определенного индекса по соображениям эффективности.

Пример:

index:  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
string: S  p  a  c  e     -  -  -     t  h  e     f  i  n  a  l     f  r  o  n  t  i  e  r
range:  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  ⬆︎ -  -  -  -  -  -  -  -  -  -  -  -
                                                     max 

Это будет означать, что я ищу строку только для совпадения регулярного выражения , которое начинается перед индексом 15.


Поведение, описанное выше, отличается от поиска только поддиапазона строки.Вот почему:

✅ Должно совпадать:

В следующем примере должно быть найдено совпадение в диапазоне [5–9], поскольку совпадение начинается до максимального индекса (= 7).

index:  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
string: S  p  a  c  e     -  -  -     t  h  e     f  i  n  a  l     f  r  o  n  t  i  e  r
range:  +  +  +  +  +  +  +  ⬆︎ -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
                             max 

❎ Должно, но не совпадать:

Если бы я искал подстроку с максимальным индексом (= 7), регулярное выражение не смогло бы совпадать, потому что часть совпадениябудет усечено.

index:  0  1  2  3  4  5  6  7  
string: S  p  a  c  e     -  -  
range:  +  +  +  +  +  +  +  ⬆︎ 
                             max 

Как этого добиться?

1 Ответ

0 голосов
/ 25 февраля 2019

Поскольку вы используете группу захвата, я предполагаю, что это строка, которую вы ищете.Вы можете изменить свое выражение на это: ^.{0,6}\\s{1,3}(---+)\\s*.Я добавил следующее:

  • ^ начало строки.
  • . {0,6} для соответствия от нуля до шести символов.

Изменение выражения, подобного этому, будет соответствовать тому, что вы ищете, ваше исходное выражение будет совпадать, если оно начинается максимум в позиции 6 , это ваш макс..Разница в том, что все совпадение содержит эти необязательные символы, но первая группа захвата будет содержать только те черты, которые вы ищете.

Я использую следующий код на игровой площадке для проверки нового выражения:

let regexString = "^.{0,6}\\s{1,3}(---+)\\s*"
let regex = try? NSRegularExpression(pattern: regexString)
let string = "Space --- the final frontier --- these are the voyages of the     
             starship Enterprise. Its continuing mission: to explore strange 
             new worlds. To seek out new life and new civilizations. To boldly   
             go where no one has gone before!"

let matches = regex?.matches(in: string, options: [], range: NSRange(location: 0, length: string.count))
if let firstMatch = matches?.first {
    print("Whole regex match starts at index: \(firstMatch.range.lowerBound)")
    print("Whole match: \(String(string[Range(firstMatch.range, in: string)!]))")
    print("Capture group start at index: \(firstMatch.range(at: 1).lowerBound)")
    print("Capture group string: \(String(string[Range(firstMatch.range(at: 1), in: string)!]))")
} else {
    print("No matches")
}

Выполнение приведенного выше кода показывает следующие результаты:

Все совпадения регулярных выражений начинаются с индекса: 0

Всего совпадений: пробел ---

Начало группы захвата с индекса: 6

Строка группы захвата: ---

Если string изменяется следующим образом: let string = "The space --- the final frontier --- these are the ... результат равен:

Нет совпадений

, поскольку \\s{1,3} начинается с индекса 10 .

Надеюсь, это работает для вас.

...