var paths = [
"C:\\02\\111\\папка\\",
"C:\\_02\\111\\папка\\файл.txt",
"C:\\02\\111\\",
"C:\\02\\",
"C:\\02"
];
for(var i = 0, l = paths.length; i < l; ++i) {
var p = paths[i];
paths[i] = p + " => " + getGrandparent(p);
}
WScript.Echo(paths.join("\n"));
function getGrandparent(path) {
if(/([^\\\/]+)([\\\/]+[^\\\/]+){2}[\\\/]*$/.test(path))
return RegExp.$1;
return undefined;
}
[Upd]
Ай, не заметил еще одну страницу.
Видимо, я не понимаю смысла таких замен.
Posted: Thu Nov 08, 2012 4:12 pm
by Andrey_A_A
Infocatcher
В чем сакральный смысл получения одним выражением?
Спасибо всем за отклик... секрет
Пишу скрипт с большим функционалом (перемещение, переименование, копирование...) в параметрах вводятся рег. выраж. - тестирую.
Posted: Thu Aug 25, 2016 8:09 pm
by DV
Замечено в AkelPad 4.9.8, хотя, возможно, было и раньше.
Поиск с регулярными выражениями вверх (назад) работает значительно медленнее, чем поиск вперёд (вниз). При этом даже необязательно, чтобы строка поиска содержала метасимвол!
Пример:
1) пусть у нас есть текстовый файл размером 50 МБ;
2) в конец этого файла добавляем строки:
3) переходим к строке "line 1", ищем текст "line" вниз с установленной галочкой "Регулярные выражения". Продолжение поиска находит "line" в строках "line 2", "line 3" и "line 4" мгновенно.
4) на строке "line 4" ищем текст "line" вверх с установленной галочкой "Регулярные выражения". Каждое продолжение поиска происходит с ощутимой задержкой.
Posted: Fri Aug 26, 2016 5:38 pm
by YuS
DV wrote:Поиск с регулярными выражениями вверх (назад) работает значительно медленнее, чем поиск вперёд (вниз).
А это потому, что фактически, поиск происходит не назад, а с начала и вперед... только совпадение ищется ближайшее перед курсором, далее ближайшее перед найденным и т.д.
Posted: Sat Aug 27, 2016 8:39 pm
by DV
YuS wrote:
DV wrote:Поиск с регулярными выражениями вверх (назад) работает значительно медленнее, чем поиск вперёд (вниз).
А это потому, что фактически, поиск происходит не назад, а с начала и вперед... только совпадение ищется ближайшее перед курсором, далее ближайшее перед найденным и т.д.
Такой подход имеет смысл только когда регулярное выражение может совпасть с многострочным текстом, причём количество строк заранее неизвестно. На мой взгляд, такая ситуация возникает лишь при выполнении следующих двух условий одновременно:
1. Регулярное выражение содержит + или *
2. Настройка ". захватывает новую строку" включена.
В моём случае не то что оба, а ни одно из этих условий не выполняется. И поиск вхолостую пробегает по всему файлу.
P.S.
Отмечу, что в случаях, когда метасимволы \n или \r присутствуют явно, само наличие этих метасимволов позволяет подсчитать количество строк искомого текста. То есть в таких ситуациях, когда + или * не используются и ". захватывает новую строку" не включена, при поиске назад следует также выполнять обычный проход снизу вверх, а не с начала документа.
А тело цикла теоретически будет одинаковым что для поиска вниз, что вверх. Хотя практически, скорее всего, в теле цикла потребуются некоторые уточнения в зависимости от значения bSearchUp.
В случае явно присутствующих в регулярном выражении символов \n и \r при поиске назад будет не
Доказательством того, что это не просто теоретические выкладки, является цикл из функции doFindTextExW в QSearchFindEx.c (реализация поиска со спец. символами):
Хотя, признаюсь, обобщение алгоритма для поиска вверх и вниз далось мне нелегко.
Posted: Mon Aug 29, 2016 10:04 am
by Instructor
DV
Сложность не в определении области цикла, а в самом механизме сравнения. Поиск назад с регулярными выражениями - это почти полностью свой код, отличный от поиска вперёд. См. RegExpFunc.h.
Posted: Mon Aug 29, 2016 2:39 pm
by DV
Instructor wrote:DV
Сложность не в определении области цикла, а в самом механизме сравнения.
Разве функция AE_FindText в AkelEdit.c не содержит тот самый цикл, о котором я говорю? Если модифицировать ciCount и ciCountEnd внутри while-цикла так, чтобы вначале диапазон поиска был в районе последней строки, затем предпоследней строки и т.д., разве мы не получим нужное поведение?
Поясняю на примере: пусть в документе 10 строк, а регулярное выражение мы идентифицировали как совпадающее с 2 строками текста (например, потому, что оно содержит 1 метасимвол \n и не содержит спец.символов + или *). Тогда при поиске снизу вверх первый вызов AE_PatExec проверяет строки 9-10 (при этом реализация поиска внутри самого AE_PatExec работает сверху вниз), второй вызов AE_PatExec проверяет строки 8-9, третий вызов AE_PatExec проверяет строки 7-8 и т.д.
Posted: Mon Aug 29, 2016 4:42 pm
by YuS
DV
Вы не поняли...
Шаблоны регулярных выражений сравниваются не целиком с подстрокой, а посимвольно, причем с возвратами и поисками лучшего совпадения. Но, в любом случае, сравнение не работает в обратном направлении шаблона именно (от последнего символа шаблона к первому), т.е. сравнение всегда идет с первым символом шаблона, затем получает точку невозврата, далее идет уже сравнение со вторым и т.д. - с учётом этого, как осуществить такое сравнение в обратном направлении текста? Т.е. где парсер будет ставить точки невозврата? Текст ведь будет сравниваться с шаблоном в направлении обратном поиску, а там точка невозврата уже стоит... тупик.
Или, чтобы было нагляднее, допустим есть шаблон:
при поиске в обратном направлении, первым будет найдено совпадение во втором слоге "па", при дальнейшем сравнении шаблона, общего совпадения не будет найдено, т.к. в шаблоне есть "-\1" и тогда перед этим вторым слогом необходимо проставить точку невозврата, ок ставим её и начинаем просмотр сначала... находим первый слог "па", далее пытаемся сравнивать оставшуюся часть шаблона и натыкаемся на точку невозврата, опять неудача. Итог - совпадения не будет найдено вовсе, хотя необходимая подстрока там и присутствует.