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

Russian main discussion
Post Reply
  • Author
  • Message
Offline
Posts: 670
Joined: Thu Jun 03, 2010 8:47 am
Location: Сочи, Хоста
Contact:

Post by Andrey_A_A »

Code: Select all

.*\\(.*)\\.*\\.*
заменить $1
оставляет только 111 и там и там
.*\\(.*)\\.*\\.*(\\)+[^\\].*
заменить $1
оставляет только 02 и там и там

а надо по разному :D

Offline
Posts: 124
Joined: Tue Jun 03, 2008 10:32 pm

Post by Xephon »

Что ^.+\\(.+)\\.+\\.+\\?$
Чем $1

[v] Regular expressions
[v] Multiline

Offline
Posts: 670
Joined: Thu Jun 03, 2010 8:47 am
Location: Сочи, Хоста
Contact:

Post by Andrey_A_A »

Xephon
Большое спасибо , у меня отработало отлично
.+\\(.+)\\.+\\.+\\?
$1

/p./s.отдыхать надо иногда))

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Andrey_A_A
В чем сакральный смысл получения одним выражением? :)

Code: Select all

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]
Ай, не заметил еще одну страницу.
Видимо, я не понимаю смысла таких замен. :)

Offline
Posts: 670
Joined: Thu Jun 03, 2010 8:47 am
Location: Сочи, Хоста
Contact:

Post by Andrey_A_A »

Infocatcher
В чем сакральный смысл получения одним выражением?
Спасибо всем за отклик... секрет :D
Пишу скрипт с большим функционалом (перемещение, переименование, копирование...) в параметрах вводятся рег. выраж. - тестирую.

DV
Offline
Posts: 1250
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post by DV »

Замечено в AkelPad 4.9.8, хотя, возможно, было и раньше.
Поиск с регулярными выражениями вверх (назад) работает значительно медленнее, чем поиск вперёд (вниз). При этом даже необязательно, чтобы строка поиска содержала метасимвол!
Пример:
1) пусть у нас есть текстовый файл размером 50 МБ;
2) в конец этого файла добавляем строки:

Code: Select all

line 1
line 2
line 3
line 4
3) переходим к строке "line 1", ищем текст "line" вниз с установленной галочкой "Регулярные выражения". Продолжение поиска находит "line" в строках "line 2", "line 3" и "line 4" мгновенно.
4) на строке "line 4" ищем текст "line" вверх с установленной галочкой "Регулярные выражения". Каждое продолжение поиска происходит с ощутимой задержкой.

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

Post by YuS »

DV wrote:Поиск с регулярными выражениями вверх (назад) работает значительно медленнее, чем поиск вперёд (вниз).
А это потому, что фактически, поиск происходит не назад, а с начала и вперед... только совпадение ищется ближайшее перед курсором, далее ближайшее перед найденным и т.д.

DV
Offline
Posts: 1250
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post by DV »

YuS wrote:
DV wrote:Поиск с регулярными выражениями вверх (назад) работает значительно медленнее, чем поиск вперёд (вниз).
А это потому, что фактически, поиск происходит не назад, а с начала и вперед... только совпадение ищется ближайшее перед курсором, далее ближайшее перед найденным и т.д.
Такой подход имеет смысл только когда регулярное выражение может совпасть с многострочным текстом, причём количество строк заранее неизвестно. На мой взгляд, такая ситуация возникает лишь при выполнении следующих двух условий одновременно:
1. Регулярное выражение содержит + или *
2. Настройка ". захватывает новую строку" включена.
В моём случае не то что оба, а ни одно из этих условий не выполняется. И поиск вхолостую пробегает по всему файлу.

P.S.
Отмечу, что в случаях, когда метасимволы \n или \r присутствуют явно, само наличие этих метасимволов позволяет подсчитать количество строк искомого текста. То есть в таких ситуациях, когда + или * не используются и ". захватывает новую строку" не включена, при поиске назад следует также выполнять обычный проход снизу вверх, а не с начала документа.

DV
Offline
Posts: 1250
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post by DV »

В общем, полагаю, нам нужно что-то вроде такого:

Code: Select all

if (IsVariableMultiLineRegEx(regEx))
{
  // ищем от начала файла - как сейчас
}
else
{
  // ищем назад (снизу вверх)
}

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

Post by Instructor »

DV
Поиск с регулярными выражениями вверх не реализован, поэтому поиск вверх работает так как описал YuS.

DV
Offline
Posts: 1250
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post by DV »

Instructor wrote:DV
Поиск с регулярными выражениями вверх не реализован, поэтому поиск вверх работает так как описал YuS.
Но ведь поиск вверх - это тот же самый цикл, только не от начала к концу, а от конца в начало. Утрируя, что-то вроде:

Code: Select all

for (nLine = bSearchUp ? nLinesCount - 1 : 0; bSearchUp ? nLine >= 0 : nLine < nLinesCount; bSearchUp ? --nLine : ++nLine)
{ ... }
А тело цикла теоретически будет одинаковым что для поиска вниз, что вверх. Хотя практически, скорее всего, в теле цикла потребуются некоторые уточнения в зависимости от значения bSearchUp.
В случае явно присутствующих в регулярном выражении символов \n и \r при поиске назад будет не

Code: Select all

nLine = bSearchUp ? nLinesCount - 1 : 0
а

Code: Select all

nLine = bSearchUp ? nLinesCount - nNewLineCharCount - 1 : 0
Доказательством того, что это не просто теоретические выкладки, является цикл из функции doFindTextExW в QSearchFindEx.c (реализация поиска со спец. символами):

Code: Select all

while ( bSearchUp ? (nLine >= nLinesToCheck - 1) : (nLine <= nEditMaxLine) )
Хотя, признаюсь, обобщение алгоритма для поиска вверх и вниз далось мне нелегко.

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

Post by Instructor »

DV
Сложность не в определении области цикла, а в самом механизме сравнения. Поиск назад с регулярными выражениями - это почти полностью свой код, отличный от поиска вперёд. См. RegExpFunc.h.

DV
Offline
Posts: 1250
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post 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 и т.д.

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

Post by YuS »

DV
Вы не поняли...
Шаблоны регулярных выражений сравниваются не целиком с подстрокой, а посимвольно, причем с возвратами и поисками лучшего совпадения. Но, в любом случае, сравнение не работает в обратном направлении шаблона именно (от последнего символа шаблона к первому), т.е. сравнение всегда идет с первым символом шаблона, затем получает точку невозврата, далее идет уже сравнение со вторым и т.д. - с учётом этого, как осуществить такое сравнение в обратном направлении текста? Т.е. где парсер будет ставить точки невозврата? Текст ведь будет сравниваться с шаблоном в направлении обратном поиску, а там точка невозврата уже стоит... тупик.
Или, чтобы было нагляднее, допустим есть шаблон:

Code: Select all

(па)-\1
текст:

Code: Select all

абвг па-па абвг
при поиске в обратном направлении, первым будет найдено совпадение во втором слоге "па", при дальнейшем сравнении шаблона, общего совпадения не будет найдено, т.к. в шаблоне есть "-\1" и тогда перед этим вторым слогом необходимо проставить точку невозврата, ок ставим её и начинаем просмотр сначала... находим первый слог "па", далее пытаемся сравнивать оставшуюся часть шаблона и натыкаемся на точку невозврата, опять неудача. Итог - совпадения не будет найдено вовсе, хотя необходимая подстрока там и присутствует.

DV
Offline
Posts: 1250
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post by DV »

YuS wrote:DV
Вы не поняли...
Поясняю свою мысль картинкой:
Image
Post Reply