Регулярные выражения

Russian main discussion
  • Author
  • Message
YuS
Offline
Posts: 512
Joined: Sun Sep 15, 2013 8:25 am
Location: 013 в Тентуре, семь по Спирали, налево от Большой Медведицы

Post by YuS »

YuS wrote:
Drugmix wrote:По правилам синтаксиса ahk:
1. Только первый аргумент можно писать через пробел от команды, пропустив запятую.
Так это может в корне поменять подход к написанию регулярки. Если я правильно понял, то пробел не может являться разделителем самих аргументов? Если так, то в массиве с валидными строками это правило нарушено...
В общем, как-то так:

Code: Select all

0   "^\s*(?:(Else)(?:\s*,\s*|\s+)|(Try)(?:\s*,\s*|\s+)|([^:]{1,38}(?=::))::)*\s*(#IfWinActive\b)\s*?,?\s*?([^;,`]+(?!`.)|[^`,;]+`.|`.)*?\s*?,?\s*?([^;,`]+?(?!`.)|[^`,;]+?`.|`.)*?(\s+;.*)?\s*$" `\1=(4,${OP},0) \2=(4,${IF},0) \3=(2,${STR},0) \4=(2,${TYPE},0) \5=(2,${ATTR},#ff0000) \6=(2,${ATTR},#00ff00) \7=(3,${COMM},0)`
Не подсвечивается только та часть массива, где нарушено правило разделителей, т.е. шесть строк с тремя аргументами...

Offline
Posts: 582
Joined: Mon Apr 08, 2013 9:50 pm
Location: Win7SP1x64, APx64

Post by Drugmix »

YuS wrote:Так это может в корне поменять подход к написанию регулярки. Если я правильно понял, то пробел не может являться разделителем самих аргументов? Если так, то в массиве с валидными строками это правило нарушено...
Да, правильно поняли: нет, пробел может быть разделителем только первого аргумента от команды. Между аргументами раздилителем может быть всегда только неэкранированная запятая.
YuS wrote:Если символ экранирования "`" присутствует в конце аргумента, то значит последующий символ экранируется и является частью аргумента, т.е. при наличии комментария в строке, последующий комментарий не выдерживает условия наличия пробела перед ";", так что всё правильно, а в случае отсутствия комментария - ничего не ломается. Или таки символ экранирования может принимать другие значения, кроме, собственно, экранирования? Если да, то такую неоднозначность трудно обработать, если вообще возможно...
Ну, можно и опустить этот случай, конечно, хотя ` в конце строки поломает окраску даже тогда, когда после неё нет комментария. В принципе, просто пробел нельзя же экранировать, поэтому когда ` присутствует в конце строки (перед комментарием или когда комментария нет) он парсером просто пропускается (считается как опущенный аргумент, если в аргументе ничего кроме ` нет). Довольно редкий случай, поэтому, можно и опустить.
YuS wrote:Ну, не совсем так. Движок по регуляркам, пока достаточно точно соответствует PCRE, за исключением некоторых особенностей, но это скорее необходимость, чем прихоть. Единственный момент - очень не хватает поиска по условию, с ним было бы гораздо проще в написании регулярок...
Я не про "вообще изменить его", а лишь подправить что-то, чтоб конструкция ([^,]|(?<=`),)* нормально заработала.
YuS wrote:Не подсвечивается только та часть массива, где нарушено правило разделителей, т.е. шесть строк с тремя аргументами...
Да, я позже только заметил, что эти строки ошибочно присутствуют в "SHOULD WORK:", извините.
YuS wrote:В общем, как-то так:

Code: Select all

0   "^\s*(?:(Else)(?:\s*,\s*|\s+)|(Try)(?:\s*,\s*|\s+)|([^:]{1,38}(?=::))::)*\s*(#IfWinActive\b)\s*?,?\s*?([^;,`]+(?!`.)|[^`,;]+`.|`.)*?\s*?,?\s*?([^;,`]+?(?!`.)|[^`,;]+?`.|`.)*?(\s+;.*)?\s*$" `\1=(4,${OP},0) \2=(4,${IF},0) \3=(2,${STR},0) \4=(2,${TYPE},0) \5=(2,${ATTR},#ff0000) \6=(2,${ATTR},#00ff00) \7=(3,${COMM},0)`
Спасибо, сходу прошло все существующие тесты и даже не ломается на двух подряд идущих экранированных символа.
Спасибо огромное!
Пока что, это лучшее из всех правил и ломается только на ` в конце строки, других отхождений от канонов парсера - пока не заметил.

YuS
Offline
Posts: 512
Joined: Sun Sep 15, 2013 8:25 am
Location: 013 в Тентуре, семь по Спирали, налево от Большой Медведицы

Post by YuS »

.del
Last edited by YuS on Sun Jan 19, 2014 6:49 am, edited 1 time in total.

YuS
Offline
Posts: 512
Joined: Sun Sep 15, 2013 8:25 am
Location: 013 в Тентуре, семь по Спирали, налево от Большой Медведицы

Post by YuS »

Drugmix wrote:лишь подправить что-то, чтоб конструкция ([^,]|(?<=`),)* нормально заработала.
Так, стоп, полез в AkelHelp, а lookbehind-ы описаны там, т.е. должны работать и работают, но почему-то в шаблоне с вариантами в группе "|", происходит захват мнимого символа из шаблона просмотра. Например:

Code: Select all

((?<=d)g|(?<=`),)
найдет в тексте все "g" с предшествующим "d" и все "," с предшествующими "`", но при поиске захватывает не "g" и "," соответственно, а "dg" и "`,". Если же поиск осуществлять без вариантов в группе, по отдельности, то захват символов происходит, как и предполагается - очень похоже, что присутствует какая-то ошибка. Огромная просьба к автору проверить этот момент.

Offline
Site Admin
Posts: 6311
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

Serge Yolkin wrote:

Code: Select all

^[^d]\S+(?!.*\=)
Тестовая

Offline
Posts: 294
Joined: Tue Jul 27, 2010 11:18 pm

Post by Serge Yolkin »

Instructor
Последнюю тестовую пока не уронил. И по проблемным прошёлся - ничего, и по ранее работавшим - продолжают работать, и наэкспериментировался за 3 часа вдоволь. Работает. Подсветка на существующих файлах в норме. Завтра ещё помучаю, но энтузиазма поубавилось.

Offline
Site Admin
Posts: 6311
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

Serge Yolkin wrote:(?<=) и (?<=|) по-моему, всё-таки, снтаксическая ошибка.
Добавлено в тестовой.

Drugmix, YuS
Переписана реализация (?<=шаблон) и (?<!шаблон).

Тестовая версия

YuS
Offline
Posts: 512
Joined: Sun Sep 15, 2013 8:25 am
Location: 013 в Тентуре, семь по Спирали, налево от Большой Медведицы

Post by YuS »

Instructor wrote: Переписана реализация (?<=шаблон) и (?<!шаблон).
Теперь захватывает только предполагаемые символы.
Однако интересное поведение работы выше предложенного шаблона:

Code: Select all

([^,]|(?<=`),)*
Например, в тексте:

Code: Select all

abc,,,,,` `,`,abcfkd`,
последовательно захватываются символы:

Code: Select all

"abc"
далее четыре захвата мнимых символа между запятыми (т.е. фактически они не выделяются, конечно, но курсор четыре раза занимает положение между запятыми при нажатии "Find next")
"` `,`,abcfkd`,"
Остановка, видимо, происходит из-за наличия запятой и невыполненного условия второй части группы, но тут бы, если конечно возможно, подопнуть бы алгоритм, чтобы он не останавливался при отсутствии необходимых символов, а продолжил искать далее по тексту совпадение...

Offline
Posts: 582
Joined: Mon Apr 08, 2013 9:50 pm
Location: Win7SP1x64, APx64

Post by Drugmix »

YuS
а я считаю, что и правильно, что останавливается там. Ведь в шаблоне задана * в конце, а не +.
В конце концов, задача у пользователя же могла быть и такой "заменить каждую, удовлетворяющую шаблону строку на такой-то текст"

YuS
Offline
Posts: 512
Joined: Sun Sep 15, 2013 8:25 am
Location: 013 в Тентуре, семь по Спирали, налево от Большой Медведицы

Post by YuS »

Drugmix wrote: а я считаю, что и правильно, что останавливается там. Ведь в шаблоне задана * в конце, а не +.
Верно, согласен, посыпаю голову пеплом. Ведь сам выше говорил, что null может являться шаблоном, а тут как-то не учел этот момент. :)

Offline
Posts: 582
Joined: Mon Apr 08, 2013 9:50 pm
Location: Win7SP1x64, APx64

Post by Drugmix »

Instructor wrote:Drugmix, YuS
Переписана реализация (?<=шаблон) и (?<!шаблон).

Тестовая версия
Это просто офигенно, огромнейшая Вам благодарность за переписанную реализацию работы lookbehind'ов!
В этой версии я смог написать полностью правильно работающее правило раскраски для одной команды, с учётом, вроде как, вообще всех возможных валидных вариантов употребления этой команды.

Code: Select all

0	"^\s*(?:(Else)(\s*,\s*|\s+)|(Try)(\s*,\s*|\s+)|(.{1,38}(?=::))(::))*\s*(#IfWinActive)(?:(\s*,\s*|\s+)(([^;,\s]|(?<=`),|(?<!\s);|\s*(?!\s*?(?:;|$)))*?)?(?:(\s*(?<!`),\s*)(([^;,]|(?<=`),|(?<!\s);)*?)?)?)?\s*?((?<=\s);.*$)?$" `\1=(4,${OP},0) \2=(0,0,0) \3=(4,${IF},0) \4=(0,0,0) \5=(2,${STR},0) \6=(0,0,0) \7=(3,${TYPE},0) \8=(0,0,0) \10=(0,${ATTR},#ff0000) \11=(0,0,0) \13=(0,${ATTR},#00ff00) \14=(3,${COMM},0)`
Теперь я наконец-то смогу завершить создание примитивное IDE для autohotkey.

Как только изменения из этой тестовой версии войдут в релизную ветку - то можно будет утверждать, что теперь используя связку AkelPad+Coder plugin можно написать примитивную IDE для разных языков.

Instructor, прошу по возможности учесть и остальные пожелания связанные с функционалом IDE.

Offline
Posts: 294
Joined: Tue Jul 27, 2010 11:18 pm

Post by Serge Yolkin »

Instructor
Да, последняя тестовая очень интересная. Поигрался, жду релиза с нетерпением.

P.S. 5.0? :)

Offline
Posts: 294
Joined: Tue Jul 27, 2010 11:18 pm

Post by Serge Yolkin »

Instructor
Ещё э-э-э... забавное поведение регулярок. Воспроизводится на последних тестовых, на стабильной - всё нормально. Конструкция [] в целом работает, но если залезть на шкаф... точнее, использовать её в (?<=[]) или (?<![]), то она перестаёт любить \\

Code: Select all

(?<![s%])s
работает, а
(?<![s%\\])s
как-то не очень

Offline
Site Admin
Posts: 6311
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »


YuS
Offline
Posts: 512
Joined: Sun Sep 15, 2013 8:25 am
Location: 013 в Тентуре, семь по Спирали, налево от Большой Медведицы

Post by YuS »

Skif_off wrote:YuS

Code: Select all

TabNameFind=^([^\n]{20})[^.\n]*(?:(\.)((?(2)[^.\n]*)))*$
TabNameRep=\1..\2\3
Получаю
Ну, это уже не вопрос функционала поиска по условию, а в правильном составлении регэкспа... в общем, это в данной теме уместнее будет.
Skif_off wrote:
1.
Слияние_текстовых_файлов_в_папке.au3
Слияние_текстовых_фа...au3
2.
MINIMIZETOTRAY-RUS.TXT
MINIMIZETOTRAY-RUS.T..
3.
Quoted-Printable.au3
Quoted-Printable.au3..
1. Тут всё верно, что не так? Длина имени файла с расширением > 20 символов.
2. Тут надо корректировать регулярку. Длина имени файла с расширением >20 символов, но правило [^\n]{20} захватывает разделительную точку и для существующего регэкспа, расширение просто отсутствует...
3. См. п.2 - захвачено 20 символов и расширение отсутствует.
В общем, надо переделывать регулярное выражение, чтобы оно учитывало все варианты.
Post Reply