iPhone: RegexKit против RegexKit lite - прохождение массива занимает очень много времени - PullRequest
2 голосов
/ 06 августа 2009

Для моего приложения мне нужно посмотреть, соответствует ли URL строке регулярного выражения. поэтому я создал массив со всеми строками регулярных выражений (около 1000+ строк) и проверил их с помощью RegexKit lite:

for (NSString * aString in mainDelegate.whiteListArray) {

if (![urlString isMatchedByRegex:aString]) {

это работает, но, к сожалению, эта операция занимает очень очень много времени. не менее 20 секунд для веб-страницы, например google.com

Я пытался использовать "обычный" RegexKit.framework, потому что у него есть метод (BOOL) isMatchedByAnyRegexInArrayNSArray *) regexArray, который намного быстрее. Я могу создать приложение, но всякий раз, когда я пытаюсь запустить его, оно вылетает со следующей ошибкой:

dyld: библиотека не загружена: @executable_path /../ Frameworks / RegexKit.framework / Versions / A / RegexKit Ссылка на: / Пользователи / Reilly / Библиотека / Поддержка приложений / iPhone Simulator / Пользователь / Приложения / 7E057EA8-5CD1-465B-8102-38A53A9B5F5B / Drowser.app / Drowser Причина: изображение не найдено

Полагаю, это потому, что RegexKit не предназначен для рук? (чтобы включить RegexKit, я следовал тому, как это происходит в документации)

поэтому мой вопрос:

  1. Известен ли вам какой-нибудь более быстрый способ проверки строки, если она соответствует любому из 1000 регулярных выражений.

  2. или вы знаете, как использовать «нормальный» RegexKit на iPhone или любую другую платформу регулярных выражений, которая будет делать то, что мне нужно в секунду?

заранее спасибо

Ответы [ 3 ]

8 голосов
/ 07 августа 2009

Примечание: Я являюсь автором RegexKit et al.

Это довольно сложный ответ ..:)

Во-первых, сопоставление тысячи регулярных выражений с любой из общедоступных реализаций механизма регулярных выражений будет довольно медленным, за исключением, возможно, механизмов регулярных выражений TCL и TRE. Причина, по которой RegexKit.framework значительно превосходит RegexKitLite в этой задаче, заключается в том, что RegexKit.framework содержит немного нетривиального, оптимизированного кода для этой задачи. Причина этого в том, что он используется в Safari AdBlock, который должен выполнять массовые сопоставления регулярных выражений с URL-адресами. Он хранит список регулярных выражений в отсортированном порядке, исходя из количества успешных совпадений. Это основано на наблюдении, что некоторые шаблоны регулярных выражений, используемые в Safari AdBlock, совпадают гораздо чаще, чем другие, и попытка их первого значительно снижает количество регулярных выражений, которые необходимо попытаться определить, есть ли «попадание». Также имеется небольшой кэш с отрицательным попаданием, а также много многопоточного кода для параллельного выполнения совпадений. Ничто из этого никогда не войдет в версию Lite, поскольку это определенно не легкая функция - вероятно, 60-70 КБ кода только для реализации одной этой функции, не говоря уже об огромном объеме памяти, необходимом для сохранения тысячи скомпилированных регулярных выражений.

Использование RegexKitLite для такого сопоставления с шаблоном должно быть очень и очень медленным. Первая проблема заключается в том, что он хранит только небольшой кэш скомпилированных регулярных выражений, которые недавно использовались. По умолчанию для кэша задано значение 23, поэтому при его установке тысячи регулярных выражений каждый регулярное выражение будет компилироваться при каждом его использовании.

Как уже отмечали другие, RegexKit.framework на самом деле не настроен для использования на iPhone. Даже если вы обошли условие «связывания с внешними платформами», сборка по умолчанию RegexKit.framework не включает архитектуру arm в ее толстый двоичный файл (он включает ppc, ppc64, i386 и x86_64). Что вам действительно нужно сделать, это установить новую цель сборки, которая создает статическую библиотеку. Не очень сложно, правда.

Боюсь, что если вам нужно что-то подобрать, вам, вероятно, придется запустить свой собственный движок регулярных выражений. Вам нужен движок регулярных выражений, который может взять ваши тысячи регулярных выражений и объединить их вместе, например, "r1|r2|r3|r4". Большинство движков регулярных выражений, в частности pcre и ICU (те, которые используются RegexKit.framework и RegexKitLite соответственно), оценивают такое регулярное выражение почти слева направо. Нужен почти DFA-подобный движок, который одновременно оценивает все возможные состояния. См. эту ссылку для получения дополнительной информации. Я построил такой движок регулярных выражений, который даже обрабатывает обратные ссылки (гораздо проще сделать, чем все говорят) за ~ O(M*log2(N)) (M - размер текста, который нужно сопоставить, N - размер регулярного выражения). , но это еще не закончено. Если бы это было так, это бы решило проблему такого рода, как плазмотрон через масло.

Мне известно, что хотя бы один человек портировал RegexKit.framework на iPhone, хотя: Mobile Safari AdBlock . AFAIK, это также порт настольной версии Safari AdBlock. Я не знаю многих деталей, но я думаю, что для установки требуется взломанный iPhone.

Таким образом, я не думаю, что есть какие-либо готовые решения для разработки под iPhone, которые делают что-то близкое к тому, что вам нужно. Лучше всего, кроме создания собственного движка регулярных выражений, - заглянуть в механизм регулярных выражений TRE и попробовать некоторые эксперименты с использованием составных регулярных выражений. Будьте готовы засучить рукава, так как вам придется очень грязные руки и разбираться с кишками какао, кодировкой Unicode и всеми другими неприятными вещами - такими вещами, которые RegexKitLite заботится о вас за кулисами.

0 голосов
/ 07 августа 2009

iPhone не поддерживает встроенные фреймворки, поэтому направления туда не сработают, даже если он был построен для рук. Вы можете использовать только вещи, которые статически связаны, поэтому вам нужно либо изменить regexkit для сборки в виде статической библиотеки, либо включить его исходный код непосредственно в ваш проект.

0 голосов
/ 06 августа 2009

Копируете ли вы RegexKit.framework в папку frameworks вашего iPhone-приложения?

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