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

Я пытаюсь сопоставить слово вперед и назад в строке, но не все совпадения. Например, ища слово "AB" в строке "AAABAAABAAA", я создаю и использую регулярное выражение /AB|BA/, но оно соответствует только двум подстрокам "AB" и игнорирует подстроки "BA".

Я использую RegexKitLite на iPhone, но я думаю, что это более общая проблема регулярных выражений (я вижу такое же поведение в онлайн-тестерах регулярных выражений). Тем не менее, вот код, который я использую для перечисления совпадений:

[@"AAABAAABAAA" enumerateStringsMatchedByRegex:@"AB|BA" usingBlock:
 ^(NSInteger captureCount,
   NSString * const capturedStrings[captureCount],
   const NSRange capturedRanges[captureCount],
   volatile BOOL * const stop) { 
     NSLog(@"%@", capturedStrings[0]);
 }];

Выход:

AB
AB

3 ответа

Решение

Я не знаю, какой онлайн-тестер вы пробовали, но http://www.regextester.com/ (например) не будет рассматривать один и тот же символ для нескольких совпадений. В этом случае, поскольку ABA соответствует AB, B не рассматривается для соответствия BA. Это просто предположение, что RegexKitLite реализован аналогичным образом.

Даже если вы не учитываете зеркальный вариант, исходная строка поиска может совпадать с самой собой. Например, если вы ищете ABCA|ACBA в ABCABCACBACBA, вы получите два из четырех совпадений, поиск в обоих направлениях будет одинаковым.

Должно быть возможно найти совпадения постепенно, но, возможно, не с RegexKitLite

Я бы сказал, это невозможно за один ход. Регулярное выражение соответствует заданному шаблону и "съедает" соответствующие символы. Так что если вы ищете AB|BA в ABA первый найденный шаблон ABТогда регулярное выражение продолжит поиск на третьем A,

Таким образом, невозможно найти перекрывающиеся шаблоны с одним и тем же регулярным выражением и используя | оператор.

Я не уверен, как бы вы выполнили в точности то, что, как я думаю, вы просите, не переворачивая строку и не проверяя дважды.

Тем не менее, я полагаю, это зависит от того, что именно вы ищете. Если вы просто пытаетесь определить, встречается ли шаблон в строке вперед или назад, а не так, как он происходит, то вы можете сделать что-то вроде этого:

ABA?|BAB?

? делает последний символ необязательным на каждой стороне |, В случае AAABAAABAAAнайду ABA дважды. В случае AB это найдет ABи в случае BA это найдет BA,

Вот это с тестовыми примерами... http://regexhero.net/tester/?id=a387ae0a-1707-4d9e-856b-ebe2176679bb

Другие вопросы по тегам