Javascript.RU

PCRE depths

Название статьи PCRE глубины.
Почему-то русский заголовок этот сайт не поддерживает на данный момент, поэтому написал на английском.

Вот решился сделать класс на javascript дополняющий возможности PCRE до представленных PHP. Самое главное - сделать вывод позиции для карманов, и непоглащающий поиск назад "(?<", которого, ИМХО позарез не хватает в нативной реализации PCRE на js.
ps, может уже есть такие библиотеки на js, если знаете - скажите чтобы не изобретать велосипед. Я сторонник чтобы javascript никак не уступал по функциональности php, т.к. хочу чтобы кроме функции представления на нём держалась вся бизнес-логика сайта, за исключением средств защиты и прав доступа к сайту, и модели в обращении к базе данных и файлам.
Но для этого, я понял, что надо до предельной глубины изучить PCRE на PHP а потом какой на JS и сделать. Внешне в PCRE, вроде, всё просто, но... в различных сочетаниях это всё простое может образовать не вполне очевидные вещи... вот таким вещам и посвящена статья. Проверялось на PHP.
Итак от простого к более сложному.
Вначале скажу что не допускает синтаксис PCRE:

/\\{2}*/ не прокатывает, прокатывает /(?:\\{2})*/
может не совместимы подряд идущие квантификаторы даже когда это очевидно корректно

/^(?=abc){2}/ не прокатывает, прокатит /^(?=(?:abc){2})/
может не совместимы квантификаторы после непоглощающих скобок

Теперь работающие нюансы,
описание будет вестись в таком формате:
((
1.исходная_строка
2.регулярное_вражение примененное к строке
3.описание вхождений и карманов в них (и где они находятся в исходной строке)
){1,2} #пункты 1,2,3 могут повториться 1-2 раза.
4.вывод, если не очевиден из описания.
5. пустая строка.
)+ps # нюансы разумеется есть

ab
/a((?=b))/
вхождение-а, а дальше пустой(без б) карман.

ab
/a(?=(b))/
карманы могут быть вне вхождения - карман - b. вхождение - а.
ab
/a((?=(b)))/
будет пуст первый карман, а дальше с б второй карман

aa
/(a)+/
карман - последняя буква а

ca
/(c)|a/
во втором вхождении не будет кармана

acbc
/(?:(a)|b)(c)/
в первом вхождении 2 кармана во втором - тоже 2, но первый будет пустым с позицией -1
таким образом номера карманов строго закреплены за кр.скобкой в регулярном выражении, и не перескакивают на следующий даже если текущего нет.
если последние карманы не определены - они вообще отсутствуют.

abc
/(?<=(b))c(?<=(a)bc)/
совпадение - с, первый карман - b, второй карман - a,
abc
/(?=ab(c))(?=a(b))a/
вхождение - а, первый карман - с, второй карман - b
Карманы идут в том поядке в каком определены в регулярном выражении,
а не в результате, в результате - в противоположном может даже быть

acacacabcabc
/(a(?:b)*c)+?(?=abc)/
в первом вхождении в кармане последняя ас, сработало всё корректно, значит
допустимо использовать минимальное поглощение совместно с непоглощающим для него условием.

abcabcac
/((a(?:b)*c)+?)+/
первый и второй карман будут последние ас
abcabcac
/((?=ab)(a(?:b)*c)+?)+$/
первый карман уже содержит последний abcac, а второй последний ас
В итоге я выяснил что минимизация квантификатора происходит не только по условию впереди, но и по скобкам с квантификаторами в которых находится, а они сжимают по самый минимум.

abcabc
/((?=ab)(a(?:b)*c)*?)+/
%1-3 ссылки на интересные следствия ниже
всего 4 вхождений, 1и3 дают два пустых камана на 0ой(для 1 вхождения) и соответсвенно на 3ей позиции(для 3вхождения).
2 - даёт пустой первый карман 3ей позиции, и второй заполненный%2 abc карман 0ой позиции. Второй заполненный карман с первой итерации + сохранился, а заполнился он (a(?:b)*c)*? благодаря механизму%1 предотвращающего бесконечный цикл по сценарию первого пустого вхождения.
4 - оба кармана заполены abc карман 3ой позиции. т.е. первый карман в отличае от 2 вхождения не является пустым, т.к. процесс остановился%3 на последнем abc при первой же итерации квантификатора+.
Тут несколько интересных следствий:
1.механизм предотвращающий бесконечный цикл:
если на одном вхождении получен пустой результат, то *? считается уже с +?
2.сохранение второго кармана с первой итерации квантификатора + при втором вхождении, это при отсутствии его во второй итерации.
3.при если конец нахождения с квантификатором сошелся с концом строки, то остальные его нахождения (заведомо пустые, даже если они есть) уже не рассматриваются.

ps.
Теперь мне осталось разобраться с детальной работой механизма предотвращающего циклы(если знаете - напишите о них плз.). И узнать в чём логика работы с вложенными квадратными скобками, они дают странные результаты, например
а9
/[a9]+/
даёт адекватный результат а9.
в то время как /[a[9]]+/ не срабатывает, а в других случаях и вовсе содержат много пустых вхождений. Если знаете на этот счёт информацию, просьба - написать.

+1

Автор: Гость (не зарегистрирован), дата: 6 апреля, 2011 - 12:58
#permalink

Ничего не понятно - статья написана для себя
Не расшифровано что такое есть PCRE, для чего оно нужно...


Автор: Matre, дата: 7 апреля, 2011 - 13:30
#permalink

PCRE — Perl Compatible RegExps
В статье описаны тонкости в синтаксисе регэкспов по этому стандарту, которые используются и в JS.


Автор: mister_maxim, дата: 16 мая, 2011 - 12:29
#permalink

Отчасти Вы правы - и для себя тоже.
Но вообще предполагается, что читатель, увидя незнакомое слово (как Вы увидели PCRE) хотя бы зайдет на ru.wikipedia.org и посмотрит его.
Конечно, если бы я писал самоучитель для новичков с основами, то мне было бы не простительно не дать определения этому слову.
Но данная статья таковой не является, она отображает мой опыт более детального изучения PCRE, о тех моментах которые в Интернете врядли найдешь, тогда как основ PCRE - в Интернете и так полно.


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
9 + 8 =
Введите результат. Например, для 1+3, введите 4.
 
Поиск по сайту
Другие записи этого автора
mister_maxim
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Популярные таги
Последние комментарии
Последние темы на форуме
Forum