Показать полную графическую версию : [решено] 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” не предлагать и не спрашивать, кроме прочего у меня есть спортивный интерес решения поставленной задачи.
Спасибо.
прикольная задачка :)
самое "короткое" решение, которое придумал:
$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)
самое "короткое" решение, которое придумал »
:o :yahoo:
Супер!
Скажи пожалуйста, мне просто интересно, сколько времени у тебя ушло на построение этого шаблона? Я более двух часов провозился чтобы у меня вышло... да собственно ничего :sorry:
P.S
И всё же, что означает ^? И зчем знак вопроса в начале группы а потом ещё и треугольная скобка, и знак равно? Я подобное видел в шаблонах php, но так и не смог понять к чему оно, в манулах тоже смотрел, но толком ничего такого не находил...
сколько времени у тебя ушло на построение этого шаблона? »утром прочитал твой пост, пока ехал на работу в автобусе обдумал варианты, на тестирование/проверку - около часа... надо сказать, в прошлых версиях AutoIT позиционная проверка не работала - с тех пор я не проверял, а тут вдруг сработала :) в штатной справке её почему-то нет, но есть в справке к движку PCRE (Lookahead/Lookbehind assertions)
пока ехал на работу в автобусе обдумал варианты »
В уме? :o
на тестирование/проверку - около часа »
Ну всё ровно в два раза быстрее чем у меня ушло, а главное, в сотни раз эффективнее :)
в штатной справке её почему-то нет, но есть в справке к движку PCRE (Lookahead/Lookbehind assertions) »
Нужно разработчикам написать, чтобы добавили.
В уме? »
ок, если интересно - ход рассуждений примерно таков: RegExpReplace работает блоками, т.е. мы должны задействовать в замене ВСЮ строку без пропусков, тут вариантов всего два: 1) захват и обработка за ход всего блока "[+-][^+-]+", либо 2) работа посимвольно "[^+-]".
1-й подход - это "лобовой" перебор вариантов, причем с обязательной посимвольной детализацией содержимого блока (иначе как потом раскрывать в замене?), т.е придётся описать 7 комбинаций ~28 символьных позиций + метасимволы групп, сохранений и т.д. - перспектива удручающая...
2-й подход интересней, но тут одна проблема - как при обработке очередного символа восстановить результат из обработки прошлых символов?... поискать можно в двух направлениях: А) возможность "глобальных" (меж-атомарных) сохранений ($1 действительна только в пределах блока); или Б) попытаться использовать при обработке символы строки вне обрабатываемого блока.
Способ А есть в Perl и соответствует его обычным переменным, т.к. регулярные выражения - его смысловое ядро ("native inborn"), в библиотеке PCRE вроде есть именованные переменные, но описаны слабо и по ходу всё зависит от конечной сборки библиотеки... Короче, эксперименты ни к чему не привели - именованные переменные в AutoIT не работают (пока?).
Способ Б и есть та самая позиционная проверка (опережающая и ретроспективная), так хорошо описанная в книге Дж.Фридла – очень мощный приём, некоторые задачи без неё просто нерешаемы. Как уже сказал выше – в ранних реализациях RegExp они не поддерживались, тут представился повод еще раз проверить.
Нужно разработчикам написать, чтобы добавили.»
да, теперь уже нужно :)
Последние сообщения отведены в новую тему Обсуждение FAQ'а (Ча.Во) по регулярным выражениям (http://forum.oszone.net/thread-150544.html). А то уже начался сплошной :off:
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.