Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   [решено] StringRegExpReplace: Конверт. строки атрибутов файла в формат Attrib.exe (http://forum.oszone.net/showthread.php?t=150219)

Creat0R 11-09-2009 01:03 1216223

StringRegExpReplace: Конверт. строки атрибутов файла в формат Attrib.exe
 
Вступление:
И снова Регулярные выражения - я их обожаю (когда нахожу решение), и в то же время ненавижу (когда найти решение не удаётся, как сейчас например :()...

Задача:

Имеем строку следующего вида (это аттрибуты файла для FileSetAttrib): "+RAT-SH"
Нужно её преобразовать в такой вид: " +R +A +T -S -H"

Т.е по сути нужно найти группу после знака модификации (+ или -), и в этой группе у каждого символа добавить пробел и найдены в начале модификатор.

Пробую так:

Код:

$sStr = "+RAT-SH"

$sResult = StringRegExpReplace($sStr, "(\+|-)([RASHNOT]){2,}", "\1\2")

ConsoleWrite($sResult & @CRLF)

Но в результате остаются лишь последние символы в каждом наборе :(.

Цель задачи:
Позволить юзеру указывать привычный формат строки атрибутов файла (как в FileSetAttrib), но при этом использовать консольную утилиту Attrib, которая использует другой формат (каждый модификатор-атрибут отдельно).

P.S
Обходные методы и вопросы типа “а зачем использовать консольный Attrib.exe а не FileSetAttrib” не предлагать и не спрашивать, кроме прочего у меня есть спортивный интерес решения поставленной задачи.

Спасибо.

amel27 11-09-2009 06:17 1216268

прикольная задачка :)
самое "короткое" решение, которое придумал:
Код:

$s = "-RASH+NOT"
$r = "[-+]?([^-+])(?<=([-+])[^-+]|([-+])[^-+]{2}|([-+])[^-+]{3}|([-+])[^-+]{4}|([-+])[^-+]{5}|([-+])[^-+]{6}|([-+])[^-+]{7})"
$x = StringRegExpReplace($s, $r, " \2\3\4\5\6\7\8\1")

ConsoleWrite($x &@CRLF)


Creat0R 11-09-2009 06:50 1216279

Цитата:

Цитата amel27
самое "короткое" решение, которое придумал »

:o :yahoo:
Супер!
Скажи пожалуйста, мне просто интересно, сколько времени у тебя ушло на построение этого шаблона? Я более двух часов провозился чтобы у меня вышло... да собственно ничего :sorry:

P.S
И всё же, что означает ^? И зчем знак вопроса в начале группы а потом ещё и треугольная скобка, и знак равно? Я подобное видел в шаблонах php, но так и не смог понять к чему оно, в манулах тоже смотрел, но толком ничего такого не находил...

amel27 11-09-2009 07:23 1216287

Цитата:

Цитата Creat0R
сколько времени у тебя ушло на построение этого шаблона? »

утром прочитал твой пост, пока ехал на работу в автобусе обдумал варианты, на тестирование/проверку - около часа... надо сказать, в прошлых версиях AutoIT позиционная проверка не работала - с тех пор я не проверял, а тут вдруг сработала :) в штатной справке её почему-то нет, но есть в справке к движку PCRE (Lookahead/Lookbehind assertions)

Creat0R 11-09-2009 15:52 1216617

Цитата:

Цитата amel27
пока ехал на работу в автобусе обдумал варианты »

В уме? :o

Цитата:

Цитата amel27
на тестирование/проверку - около часа »

Ну всё ровно в два раза быстрее чем у меня ушло, а главное, в сотни раз эффективнее :)

Цитата:

Цитата amel27
в штатной справке её почему-то нет, но есть в справке к движку PCRE (Lookahead/Lookbehind assertions) »

Нужно разработчикам написать, чтобы добавили.

amel27 12-09-2009 06:23 1217005

Цитата:

Цитата Creat0R
В уме? »

ок, если интересно - ход рассуждений примерно таков: RegExpReplace работает блоками, т.е. мы должны задействовать в замене ВСЮ строку без пропусков, тут вариантов всего два: 1) захват и обработка за ход всего блока "[+-][^+-]+", либо 2) работа посимвольно "[^+-]".

1-й подход - это "лобовой" перебор вариантов, причем с обязательной посимвольной детализацией содержимого блока (иначе как потом раскрывать в замене?), т.е придётся описать 7 комбинаций ~28 символьных позиций + метасимволы групп, сохранений и т.д. - перспектива удручающая...

2-й подход интересней, но тут одна проблема - как при обработке очередного символа восстановить результат из обработки прошлых символов?... поискать можно в двух направлениях: А) возможность "глобальных" (меж-атомарных) сохранений ($1 действительна только в пределах блока); или Б) попытаться использовать при обработке символы строки вне обрабатываемого блока.

Способ А есть в Perl и соответствует его обычным переменным, т.к. регулярные выражения - его смысловое ядро ("native inborn"), в библиотеке PCRE вроде есть именованные переменные, но описаны слабо и по ходу всё зависит от конечной сборки библиотеки... Короче, эксперименты ни к чему не привели - именованные переменные в AutoIT не работают (пока?).

Способ Б и есть та самая позиционная проверка (опережающая и ретроспективная), так хорошо описанная в книге Дж.Фридла – очень мощный приём, некоторые задачи без неё просто нерешаемы. Как уже сказал выше – в ранних реализациях RegExp они не поддерживались, тут представился повод еще раз проверить.

Цитата:

Цитата Creat0R
Нужно разработчикам написать, чтобы добавили.»

да, теперь уже нужно :)

Creat0R 14-09-2009 22:52 1219096

Последние сообщения отведены в новую тему Обсуждение FAQ'а (Ча.Во) по регулярным выражениям. А то уже начался сплошной :off:


Время: 12:24.

Время: 12:24.
© OSzone.net 2001-