101

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

Спасибо, уважаемые!

102 (изменено: Malcev, 2015-09-14 13:14:39)

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

А с чего ты решил, что там "`n" ? Там `r.

А разве это имеет значение?
Если имеет, то первый пример на оффсайте неверен:
http://ahkscript.org/docs/commands/LoopReadFile.htm
Да и сама фраза тоже:

Remember to include a linefeed (`n) after the text, if desired

В твоем скрипте вижу следующие недочеты:
1) числа сравниваются, как числа.
2) скрипт неправильно работает с количеством букв, меньшим, чем n.

text=
(
a
б
3.0
003
)

N := 3, pos := 1
while pos := RegExMatch(text, "(.{" N "}).*?(\R|$)", match, pos + StrLen(match))
   (prev == match1) ? NewText .= match : (prev := match1, NewText .= "_" . match)

msgbox % NewText

103

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

А разве это имеет значение?
Если имеет, то первый пример на оффсайте неверен

Имеет, наверно, только теоретически. Почему неверен? Там получают такой файл, какой нужен. В данном же случае это специально не оговаривалось.
Остальное легко исправляется, просто это тоже вряд ли имеет здесь значение.

while pos := RegExMatch(text, "([^\r\n]{1," N "}).*?(\R|$)", match, pos + StrLen(match))
   (prev == "" . match1) ? NewText .= match : (prev := match1, NewText .= "_" . match)
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

104 (изменено: DD, 2016-01-22 20:05:51)

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

Привет! Как захватить содержимое тегов div, но при этом, не более 100 символов? Т.е. следующие выделенные 100 символов:

<div class="pi_text">текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст</div>

Или следующие 37 символов, если в теге содержалось меньше 100 символов:

<div class="pi_text">текст текст текст текст текст текст т</div>

105 (изменено: Alectric, 2016-01-22 20:16:44)

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

StringLeft.

Win 10 x64
AHK v1.1.24.00
                       Справка тебе в помощь.

106 (изменено: Malcev, 2016-01-22 21:32:15)

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

var1 := "<div class=""pi_text"">текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст</div>"
var2 := "<div class=""pi_text"">текст текст текст текст текст текст т</div>"

loop 2
{
   RegExMatch(var%A_Index%, "<div class=""pi_text"">(?!</div>)((.(?!</div>)){0,99}.)(?=.*</div>)", match)
   msgbox % match1
}
+ DD

107

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

Спасибо большое! Возник по ходу вопрос: реально ли, именно посредством рег. выражений, получать это определенное количество символов в теге div, но чтобы граница получаемого текста не приходилась на текст в угловых скобках, т.е., чтобы как в примере ниже не отрезалось, а чтобы граница была до или после содержимого тегов? —


var1 := "<div class=""pi_text"">текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст <a href=""link""> текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст</div>"
var2 := "<div class=""pi_text"">текст текст текст текст текст текст т</div>"

loop 1
{
   RegExMatch(var%A_Index%, "<div class=""pi_text"">(?!</div>)((.(?!</div>)){0,99}.)(?=.*</div>)", match)
   msgbox % match1
}

Пробовал варианты с открывающей угловой скобкой в качестве максимальной границы, но всё не то.

108

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

а чтобы граница была до или после содержимого тегов?

Не понял. Покажите на примере, что вы хотите получить.

109 (изменено: DD, 2016-01-22 23:13:21)

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

В идеале, чтобы получаемый текст (выделенный синим) не захватывал то, что в тегах, — когда максимальное значение приходится в пределы угловых скобок (тут граница до угл. скобки):

<div class=""pi_text"">текст текст текст текст текст текст текст текст <a href=""link""> текст текст<br> текст текст <a href=""link""> текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст

Или так (тут граница после угл. скобки в месте максимального диапазона):

<div class=""pi_text"">текст текст текст текст текст текст текст текст <a href=""link""> текст текст<br> текст текст <a href=""link""> текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст

Не так:

<div class=""pi_text"">текст текст текст текст текст текст текст текст <a href=""link""> текст текст<br> текст текст <a href=""link""> текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст

110

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

doc := ComObjCreate("htmlfile")

text = <div>654321</div>
doc.write(text)
doc.close()
MsgBox % SubStr(doc.body.innerText, 1, 3)

text = <div>аб<a href="http://script-coding.com">вг</a>де</div>
doc.write(text)
doc.close()
MsgBox % SubStr(doc.body.innerText, 1, 3)

111 (изменено: Malcev, 2016-01-23 03:43:40)

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

var1 := "<div class=""pi_text"">текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст <a href=""link""> текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст</div>"
var2 := "<div class=""pi_text"">текст текст текст текст текст текст т</div>"

loop 2
{
   RegExMatch(var%A_Index%, "<div class=""pi_text"">(?!</div>)((.(?!</div>)){0,99}.)(?=.*</div>)", match)
   msgbox % RegExReplace(match1, "<[^>]*$")
}

shiz, ваш код не сохраняет в переменной теги  между div.
А судя по выделенному синим это необходимо.

+ DD

112

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

Malcev, не уверен, что необходимо, иначе может получиться, что будет захвачен открывающий тег без закрывающего.

113 (изменено: DD, 2018-05-14 23:33:42)

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

Спасибо, нужно было именно регулярное выражение. На всякий случай: может дано представить на них обработку из следующих двух строк — единым выражением? —

RegExMatch(var%A_Index%, "<div class=""pi_text"">(?!</div>)((.(?!</div>)){0,99}.)(?=.*</div>)", match)
   msgbox % RegExReplace(match1, "<[^>]*$")

114

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

shiz пишет:

…иначе может получиться, что будет захвачен открывающий тег без закрывающего.

Как понимаю, не по теме, но на этом пути можно было бы получить и HTML-теги с закрытием тех, содержимое которых захвачено не полностью (правда «нормализованные» IE по-своему):

doc := ComObjCreate("htmlfile")

text = <div>аб<a href="http://script-coding.com">вг</a>де</div>
doc.write(text)
doc.close()
TextRange := doc.selection.createRange()
; TextRange.moveStart("character", 0)
TextRange.moveEnd("character", 3)
MsgBox % TextRange.htmlText

115

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

По какой причине, при чтении файла (ANSI), не отрабатывает замена любых знаков на `n, хотя если содержимое файла добавить в виде переменной в скрипт, то замены производятся?


Srt := RegExReplace(Srt, "`t", "`n")
Srt := RegExReplace(Srt, "\t", "\n")

116 (изменено: belyankin12, 2017-02-19 19:55:27)

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

Задам свой вопрос сюда, вместо создания новой темы, ибо заголовок соответствует. Если я был не прав, да простят меня модераторы.

Собственно у меня в текстовом файле есть строка:

+ Nick_Name - Reason

Мне нужно с помощью RegExReplace (это важно), присвоить переменные + Nick_Name и Reason. Соответственно - не брать в переменную.  Мой гуру-наставник по AHK просто не может сейчас мне помочь, а он меня научил выделять в этой функции только что-то до или после определенного символа.

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

117

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

DD
Первая строка должна работать без проблем. Вторая нет, т.к. в строке замены Escape-последовательности не указываются.


belyankin12 пишет:

присвоить переменные ... не брать в переменную

Нормальным языком, пожалуйста.

118

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

Соответственно тире не брать в переменную. Так понятно? У меня в результате, грубо говоря, var1 = "+" var2 = "Nick_Name" var3 = "Reason" должно выйти.

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

119 (изменено: migomigo, 2017-02-19 21:23:14)

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

Src = Isdfmnc_Fldscnqwo_1:805 "`n" "asdfasdfasdfasdfasdfasdfasdfasdf"

Var := RegExMatch(Src, "\:.*$", Found)   ; Как сделать что-бы Found вернул  "805"

MsgBox, % Found

Подскажите пожалуйста, как сделать что-бы Found вернул  "805"?

AutoHotKey Version: 1.1.09.02
Не спеши, а то успеешь..

120

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

belyankin12
Так годится?:

Str := "+ Nick_Name - Reason"

Var := StrSplit(RegExReplace(Str, "( -?)+", "|"), "|")

MsgBox, % Var.1 "`n" Var.2 "`n" Var.3

Loop % Var.MaxIndex()
   MsgBox, % Var[a_index]

migomigo

Src = Isdfmnc_Fldscnqwo_1:805 "`n" "asdfasdfasdfasdfasdfasdfasdfasdf"

Var := RegExMatch(Src, "\:(\d+)", Found)
MsgBox, % Found1

Found := RegExReplace(Src, ".+\:(\d+).+", "$1")
MsgBox, % Found

121 (изменено: migomigo, 2017-02-19 21:57:41)

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

Flasher

Вот так:

Src = Isdfmnc_Fldscnqwo_1:805 "`n" "asdfasdfasdfasdfasdfasdfasdfasdf"
Found := RegExReplace(Src, ".+\:(\d+).+", "$1")
MsgBox, % Found

работает идеально.


А вот так:

Src1 := "Time_Limits_1:605"
Found1 := RegExReplace(Src1, ".+\:(\d+).+", "$1")  ;= Возвращяет цыфру в строе после знака ":"
MsgBox, % Found1

теряет последнюю цифру.

AutoHotKey Version: 1.1.09.02
Не спеши, а то успеешь..

122

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

migomigo
Я же не в курсе вариаций. В строке поиска вместо + нужна * на конце.

123

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

Спасибо.

AutoHotKey Version: 1.1.09.02
Не спеши, а то успеешь..

124 (изменено: belyankin12, 2017-02-19 22:53:43)

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

Flasher, почему-то я думал, что это очевидно, но похоже я был не прав. На месте + может стоять и - и = .  Мне нужна переменная, которая её выведет а в зависимости от того, что там стоит, я уже буду условие делать.

Давайте по-другому объясню. У меня сейчас есть запись такого вида:


Nick_Name - Reason

Вывожу переменные я так:


UnName := RegExReplace(line, "\ -.*", "")
UnReson := RegExReplace(line, ".*-", "")

А я хочу, чтобы у меня было все тоже самое, только я мог записать + - или = в строчку ("+ Nick_Name - Reason") и в зависимости от того, что там стоит, развивать условие. Nick_Name может быть любым, но у него обязательно есть _ между параметром Nick и Name. Reason тоже может быть разным, но он всегда стоит после тире и одного пробела.

Соответственно в конкретно этом случае переменная UnName должна быть равна "Nick_Name", переменная UnReason = "Reason", а какая-то переменная var = "+" "-" или "=", в зависимости от того, что там стоит.

Мой гуру-наставник как-то мне объяснял о RegExReplace, что можно ловить текст в переменную не только до или после определенного символа (как я сейчас вылавливаю переменную), но и внутри текста, между двумя какими-то символами, но я был невнимательным .

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

125

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

Приведете полные примеры строк и что вы хотите получить.

126

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

belyankin12
Убрал первые '-?' из подвыражения. Этого достаточно?

127 (изменено: belyankin12, 2017-02-19 23:28:34)

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

Malcev, Я вам запишу это так, как я умею, через RegExMatch, а вы преобразуете это в RegExReplace, с сохранением имен переменных.


line := "+ Nick_Name - Reason"

if RegExMatch(line, "(.*) (.*) - (.*)", end_str)

UnName := end_str2
UnReason := end_str3
var := end_str1

if (var = "+") {
msgbox, Плюс
} else if (var = "=") {
msgbox, Равно
} else if (var = "-") {
msgbox, Минус
}
Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

128

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

Flasher, да, так работает, но я ничего совсем не понимаю в вашем коде. Могли бы вы сделать его пусть и нерациональным, но более понятным? Без объединения всех переменных сплитом, а созданию трех разных переменных.

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

129

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

А чем вас ваш вариант не устраивает?

130 (изменено: belyankin12, 2017-02-19 23:36:00)

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

Malcev, я задал этот вопрос не потому что не могу решить проблему, а потому, что я не знаю как пользоваться RegExReplace. На таком простом примере я смогу понять некие азы, ведь есть моменты, когда ExReplace сработает лучше, чем ExMatch (не зря же эту команду придумали), а кроме вас, больше мне некого спросить .

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

131

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

А он для вашего случая и не преднозначен.
Когда вам понадобится что-то заменить, тогда его и используйте.
Replace - замена.
Match - совпадение.

132 (изменено: belyankin12, 2017-02-19 23:45:56)

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

Вы не поняли, я пытаюсь сейчас с помощью ExReplace научится находить совпадения. А в будущем это мне может понадобится, когда понадобится замену производить (чтобы в таком случае не использовать сначала ExMatch а потом ExReplace).

Ту проблему, что я показал вам, я решил давно уже с помощью ExMatch. Но знаниям же предела нет .

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

133

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

belyankin12
А что именно непонятно?

Str := "+ Nick_Name - Reason"
Var := RegExReplace(Str, "( -?)+", "|")   ; замена пробела или комбинации пробела с '-' на |
Var := StrSplit(Var, "|")   ; массив по сепаратору "|"

MsgBox, % Var.1
MsgBox, % Var.2
MsgBox, % Var.3

134 (изменено: belyankin12, 2017-02-20 00:18:30)

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

Flasher, вот посмотрите, как я понимаю то, что тут написано. Все, что до - идёт (+ Nick_Name ) заменяется на |, а потом идёт команда StrSplit, назначение которой я могу примерно перевести, что это соединяет строки между собой она. Непонятно откуда скрипт по отдельности выводит + и Nick_Name. Ну и непонятно, откуда скрипт узнает параметр Reason.

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

135

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

Flasher, способ ненадежный, так как в нике может быть символ "|".

136

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

belyankin12
Там же в комментарии написано "пробела или комбинации пробела с '-'". Поэтому "Все, что до - идёт (+ Nick_Name )" неверно. Пробел есть между плюсом и Nick_Name? Есть. Так же, есть пробел до Reason.

Malcev
Не встречал таких ников. Ну, можно | на `r заменить, не суть.

137

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

Flasher, часть понял. Т.е. после ExReplace выражение в памяти сохранилось так:

+|Nick_Name|Reason

Верно? Если я прав, я уже логически понимаю как работает strsplit, он просто создает массив с переменными до первого |, после  первого и до второго | и после второго |. Так?

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

138

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

belyankin12
Примерно. Строка сохранилась в переменной Var, далее она преобразуется в массив, разбивая строку по заданному разделителю. Разделителей всегда на один меньше, чем создаваемых элементов массива.

139

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

Все понятно, спасибо.

Когда вы говорите что не можете сделать, вам всего-лишь не хватает фантазии придумать какой-нибудь костыль.

140

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

Подскажите пожалуйста!

var = 
(
Time_Limits_1:В Контакте
ВКонтакте
Берлога - Чат
Однокласники
@Mail.ru
порно
сериал
Home - ROBLOX
ok.ru
http://worldoftanks.ru
ROBLOX
)

RegExReplace_var := RegExReplace(var, "", "$1")



; Как убрать в начале переменной "Time_Limits_1:"
; что-бы получилось:

RegExReplace_var = 
(
В Контакте
ВКонтакте
Берлога - Чат
Однокласники
@Mail.ru
порно
сериал
Home - ROBLOX
ok.ru
http://worldoftanks.ru
ROBLOX
)
AutoHotKey Version: 1.1.09.02
Не спеши, а то успеешь..

141

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

migomigo

RegExReplace_var = % SubStr(var, 15)
; либо:
RegExReplace_var := RegExReplace(var, "^\w+:")

142

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

Flasher
Спасибо, то что надо.

AutoHotKey Version: 1.1.09.02
Не спеши, а то успеешь..

143 (изменено: DD, 2017-03-09 22:36:24)

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

С каким шаблоном удалить из списка папки, дублирующие имеющиеся в списке папки с файлами, т.е. выделенные? —

C:\IE
C:\IE\t=27229.html
C:\Temp\FXSAPIDebugLogFile.txt
C:\Temp\flashgot.Profile\FlashGot.exe
C:\Temp\flashgot.Profile
C:\Program Files\Common Files\System
C:\Program Files\Common Files
F:\APPs\AdvOR-0.3.0.20\AdvOR\AdvOR.ini

144 (изменено: stealzy, 2017-03-10 00:37:43)

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

InStr() в цикле - расчет за N² операций (если самый простой алгоритм — проверить вхождение каждого элемента в каждом), где N — длина списка.
Причем тут RegEx?

145

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

Для начала нужно определиться, что считать за файл, а что за директорию, так как:
C:\Program Files\Common Files\System - может быть файлом.
C:\Temp\flashgot.Profile\FlashGot.exe - может быть директорией.

146

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

Malcev, судя по примеру, нет нужды различать папки и файлы,
просто оставить элемент с самым длинным путем, элементы с входящими в него путями — удалить.

147

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

Malcev
Возможно, по атрибутам объектов, которые можно проверять, выделив пары? Но в моём случае это не требуется, потому что там пути с разницей в уровень, всегда будут файлом и папкой.

148

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

stealzy, если бы было так, то C:\Program Files\Common Files было бы выделенным.

149

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

DD, разве?

DD пишет:

C:\Program Files\Common Files\System
C:\Program Files\Common Files

150

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

DD, ну да, System очевидно файл.
Наверно вам стоит новую тему начать.

151

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

Malcev, ей-Богу))
stealzy, похоже, что вам не стоит советовать, потому что System — папка, а с RegEx тоже можно сделать, хотя и не принципиально)).

152 (изменено: DD, 2017-03-10 00:55:09)

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

Malcev, то есть, System — это просто пример, который указал, чтобы не было ориентации на расширение и которую надо считать за файл. Таким образом, удаляется всё, у чего есть дубликат — уровнем выше.

153 (изменено: Malcev, 2017-03-10 05:23:30)

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

Без предварительной сортировки не знаю как:

var=
(
C:\IE
C:\IE\t=27229.html
C:\Temp\FXSAPIDebugLogFile.txt
C:\Temp\flashgot.Profile\FlashGot.exe
C:\Temp\flashgot.Profile
C:\Program Files\Common Files\System
C:\Program Files\Common Files
F:\APPs\AdvOR-0.3.0.20\AdvOR\AdvOR.ini
)
Sort var
msgbox % RegExReplace(var,"sm`a)^(.+)\R(?=.*\1\\)")
+ DD

154

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

По простецкому так наверное:


var=
(
C:\IE
C:\IE\t=27229.html
C:\Temp\FXSAPIDebugLogFile.txt
C:\Temp\flashgot.Profile\FlashGot.exe
C:\Temp\flashgot.Profile
C:\Program Files\Common Files\System
C:\Program Files\Common Files
F:\APPs\AdvOR-0.3.0.20\AdvOR\AdvOR.ini
)

Loop, Parse, var, `n
	If !InStr("`n" var, "`n" A_LoopField "\")
		List .= (List = "" ? "" : "`n") A_LoopField
MsgBox % List

Malcev а что значит "1" в шаблоне, совпадение первого подшаблона? И .* не лишнее?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui
+ DD

155 (изменено: Malcev, 2017-03-10 22:28:50)

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

serzh82saratov, да, совпадение первого подшаблона.
.* не лишнее, например, в таком случае:

var=
(
C:\IE
C:\IE.
C:\IE\t=27229.html
)
Sort var
msgbox % RegExReplace(var,"sm`a)^(.+)\R(?=.*\1\\)")

156

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

Спасибо!

157 (изменено: teadrinker, 2017-03-11 02:07:42)

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

var=
(
C:\Temp\flashgot.Profile
C:\IE
C:\Program Files\Common Files
C:\Temp\FXSAPIDebugLogFile.txt
C:\Program Files\Common Files\System
C:\Temp\flashgot.Profile\FlashGot.exe
F:\APPs\AdvOR-0.3.0.20\AdvOR\AdvOR.ini
C:\IE\t=27229.html
)
MsgBox, % RegExReplace(var,"sm`a)^(.+)\\.*\K^\1(\R|$)|^(.+)(\R|$)(?=.*^\3\\)")
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

158

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

Аа-а, без сортировки. Спасибо, круто.

159

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

teadrinker интересный шаблон, если не сложно можешь рассказать что да как в нём.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

160

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

RegExReplace(var,"sm`a)^(.+)\\.*\K^\1(\R|$)|^(.+)(\R|$)(?=.*^\3\\)")

Если s в опциях — точка означает любой символ, включая любые возможные переносы строк.
m`a — символы ^ и $ означают начало и конец строк (а не начало и конец шаблона).
^(.+)\\.*\K — часть перед \K не включается в замену, а только говорит о том, что должно быть в начале.
\1 — ссылки на подшаблоны по порядковому номеру.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

161

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

Подскажите, пожалуйста, как от заголовка страницы оставить только название темы?
До:

AHK: Регулярные выражения (Страница 7) — AutoHotkey — Общение — Серый форум - Google Chrome

После:

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

Win10x64, AHK v1.1.25

162

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

Header = AHK: Регулярные выражения (Страница 7) — AutoHotkey — Общение — Серый форум - Google Chrome
msgbox % RegExReplace(Header, "[\w: ]*([^(]+) \(.+", "$1")

Выражение слева направо: необязательное множество в квадратных скобках любой латиницы, двоеточия и пробела, подвыражение в скобках из множества любых символов, отличных от открывающей скобки, далее - пробел, сама скобка и множество любых символов. В $1 попадает всё, что попало в подвыражение.

163

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

Flasher, спасибо! Это выражение будет работать с любыми темами из данной ветки? Могли бы Вы добавить комментарии ко второй строке?

Win10x64, AHK v1.1.25

164

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

becauseim
Теперь да. Добавил.

165 (изменено: Flasher, 2017-03-24 20:23:32)

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

becauseim пишет:

Это выражение будет работать с любыми темами из данной ветки?

Конечно нет.
Правильно так:

Header = AHK: IfWinNotActive для всех полноэкранных приложений (Страница 1) — AutoHotkey — Общение — Серый форум - Google Chrome
msgbox % RegExReplace(Header, "(AHK: ?)?([^(]+) \(.+", "$2")
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

166

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

Flasher, к сожалению не успел прочитать, что вы ответили, так как всё уже потёрто.
Кстати, ваш код неверен:

Header = AHK: Sockets (Страница 1) — AutoHotkey — Общение — Серый форум - Google Chrome
msgbox % RegExReplace(Header, "[\w: ]*([^(]+) \(.+", "$1")

167

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

Flasher, спасибо за комментарии! Но если в названии темы идут слова на латинице или цифры, то они не выводятся. В варианте от teadrinker такого не наблюдается.
teadrinker, если несложно, добавьте коментарии к Вашему варианту.

Win10x64, AHK v1.1.25

168

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

Ну у teadrinkera тоже не идеальный вариант.

Header = AHK: Перенести содержимое переменной (Loop, Parse) (Страница 1) — AutoHotkey — Общение — Серый форум - Google Chrome
msgbox % RegExReplace(Header, "(AHK: ?)?([^(]+) \(.+", "$2")

Я бы сделал так:

Header = AHK: Перенести содержимое переменной (Loop, Parse) (Страница 1) — AutoHotkey — Общение — Серый форум - Google Chrome
msgbox % RegExReplace(Header, "AHK:\s*(.*) \(Страница.*", "$1")

169

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

Malcev
Во всех случаях проблемы. Тогда уж так:

Header = Восстановление подключения Интернет при обрыве связи (Страница 1) — AutoHotkey — Общение — Серый форум
msgbox % RegExReplace(Header, "i)(AHK:\s*)?(.*) \(Страница \d+\) — .*", "$2")

И, полагаю, всё же лучше забирать не из заголовка, а из кода в <h1 class="main-title">.

170 (изменено: becauseim, 2017-03-25 16:17:11)

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

Flasher, спасибо! Последний вариант выглядит значителньо иначе. Дайте комментарии к нему, пожалуйста. Желательно с видимым разделением.

+ Например:

"i) Описание
(AHK:\ Описание
s*)?(.*) \ Описание
(Страница \
d+\
) — .*", "$2")

Win10x64, AHK v1.1.25

171

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

becauseim
Мне кажется, проще будет, если напишите, что именно неясно, исходя из справочной информации.

172 (изменено: Malcev, 2017-03-25 17:16:14)

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

Flasher пишет:

Во всех случаях проблемы.

Ну я бы назвал их исключениями, а не случаями.
Их, кстати, гораздо больше: AutoHotKey:, AHK_L:,WSH or AHK:....
Возможно кто-нибудь AHK напишет кириллицей (АНК) дабы не менять язык.
Всех все-равно не учтёшь.
Можно так:

Header = AutoHotKey: Передача указателя между двумя процессами (скриптами) (Страница 1) — AutoHotkey — Общение — Серый форум
msgbox % RegExReplace(Header, "(.*?(:|-)\s*)?(.*) \(Страница.*", "$3")
Flasher пишет:

полагаю, всё же лучше забирать не из заголовка, а из кода в <h1 class="main-title">.

А разница?

173

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

Malcev пишет:

Ну я бы назвал их исключениями, а не случаями.

Я их называю кодами.

Malcev пишет:

Всех все-равно не учтёшь.

Можно так: ([\wА-я]*:\s*)?

Malcev пишет:

А разница?

Там только заголовок темы, без "мусора".

174

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

Мусор-то как-раз несложно убрать (легче, чем получить его из кода страницы).
Вариант кода из 72 поста вроде работает, (если, конечно, не брать во внимание темы без префикса , но с двоеточим либо тире).
Но таких я на форуме беглым взглядом не нашёл.

175

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

Вообще кроме - там может быть и —. Да и пробельные символы в префиксе лучше исключить: [^\s]*.

176

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

Пробельные символы не надо исключать, а вот цифры стоит:

Header = WSH or AHK: Копирование выделенных ссылок (Страница 1) — AutoHotkey — Общение — Серый форум
msgbox % RegExReplace(Header, "(\D*?(:|-|—)\s*)?(.*) \(Страница.*", "$3")

177

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

Цифры тоже нужны: AU3 вместо AutoIt.

178 (изменено: Malcev, 2017-03-25 17:59:55)

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

Тогда так:

Header = WSH or AHK: Копирование выделенных ссылок (Страница 1) — AutoHotkey — Общение — Серый форум
msgbox % RegExReplace(Header, "(.*?(:|-|—)\s*)?(.*)(?= \(Страница).*", "$3")

179

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

Всё-равно проблемы с этим дефисом. Скажем, в комьюнити заголовок "Веб-сайт www.blabla.org возвращает 404".

180

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

Судя по всему автора интересует только данная ветка:

becauseim пишет:

Это выражение будет работать с любыми темами из данной ветки?

181

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

Можно убрать "в комьюнити", суть не изменится.
WSH or AHK - это ведь тоже что-то с чем-то.

182

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

Header = Веб-сайт www.blabla.org возвращает 404 (Страница 1) — AutoHotkey — Общение — Серый форум
msgbox % RegExReplace(Header, "i)(.*?(ahk|autohotkey|анк).*?(:|-|—)\s*)?(.*)(?= \(Страница).*", "$4")

183

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

.*?(.|анк).*? - это зачем? Могут быть Танки, Банкнота, Анкета и т.д.

184 (изменено: Malcev, 2017-03-25 19:29:13)

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

Для таких случаев.
Вставил границы:

Header = АНК: Отслеживание "родного" или текущего разрешения экрана (Страница 1) — AutoHotkey — Общение — Серый форум
msgbox % RegExReplace(Header, "i)(*UCP)(.*?(ahk|autohotkey|\bанк\b).*?(:|-|—)\s*)?(.*)(?= \(Страница).*", "$4")

185 (изменено: becauseim, 2017-04-06 12:51:36)

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

Подскажите, пожалуйста, как удалить первые три строки и первые три символа из четвертой строки? Результат в данном случае должен выдать три нуля.
Пытался удалить строки с помощью TF.ahk, но не получается. Первое значение функции вводил по-разному, в кавычках и без.

+ TF.ahk
/*
Name          : TF: Textfile & String Library for AutoHotkey
Version       : 3.6
Documentation : https://github.com/hi5/TF
AHKScript.org : http://www.ahkscript.org/boards/viewtopic.php?f=6&t=576
AutoHotkey.com: http://www.autohotkey.com/forum/topic46195.html (Also for examples)
License       : see license.txt

Credits & History: See documentation at GH above.

Structure of most functions:

TF_...(Text, other parameters)
	{
	 ; get the basic data we need for further processing and returning the output: 
	 TF_GetData(OW, Text, FileName)
	 ; OW = 0 Copy inputfile 
	 ; OW = 1 Overwrite inputfile
	 ; OW = 2 Return variable
	 ; Text : either contents of file or the var that was passed on
	 ; FileName : Used in case OW is 0 or 1 (=file), not used for OW=2 (variable)

	 ; Creates a matchlist for use in Loop below
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; A_ThisFunc useful for debugging your scripts

	 Loop, Parse, Text, `n, `r
		{
		 If A_Index in %TF_MatchList%
			{
			...
			}
		 Else 
			{
			...
			}
		}
	 ; either copy or overwrite file or return variable
	 Return TF_ReturnOutPut(OW, OutPut, FileName, TrimTrailing, CreateNewFile) 
	 ; OW 0 or 1 = file
	 ; Output = new content of file to save or variable to return
	 ; FileName
	 ; TrimTrailing: because of the loops used most functions will add trailing newline, this will remove it by default
	 ; CreateNewFile: To create a file that doesn't exist this parameter is needed, only used in few functions
   }

*/

TF_CountLines(Text)
	{ 
 	 TF_GetData(OW, Text, FileName)	 
 	 StringReplace, Text, Text, `n, `n, UseErrorLevel
	 Return ErrorLevel + 1
	}

TF_ReadLines(Text, StartLine = 1, EndLine = 0, Trailing = 0)
	{
	 TF_GetData(OW, Text, FileName)	 
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 Loop, Parse, Text, `n, `r
		{
		 If A_Index in %TF_MatchList%
			OutPut .= A_LoopField "`n"
		 Else if (A_Index => EndLine)
			Break
		}
	 OW = 2 ; make sure we return variable not process file
	 Return TF_ReturnOutPut(OW, OutPut, FileName, Trailing)
	}

TF_ReplaceInLines(Text, StartLine = 1, EndLine = 0, SearchText = "", ReplaceText = "")
	{
 	 TF_GetData(OW, Text, FileName)
	 IfNotInString, Text, %SearchText%
	 	Return Text ; SearchText not in TextFile so return and do nothing, we have to return Text in case of a variable otherwise it would empty the variable contents bug fix 3.3
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 Loop, Parse, Text, `n, `r
	 	{
		 If A_Index in %TF_MatchList%
			{
			 StringReplace, LoopField, A_LoopField, %SearchText%, %ReplaceText%, All
			 OutPut .= LoopField "`n"
			}
		 Else
			OutPut .= A_LoopField "`n"
		}		
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

TF_Replace(Text, SearchText, ReplaceText="")
	{
	 TF_GetData(OW, Text, FileName)
	 IfNotInString, Text, %SearchText%
	 	Return Text ; SearchText not in TextFile so return and do nothing, we have to return Text in case of a variable otherwise it would empty the variable contents bug fix 3.3
	 Loop
		{
		 StringReplace, Text, Text, %SearchText%, %ReplaceText%, All
		 if (ErrorLevel = 0) ; No more replacements needed.
			break
		}
	 Return TF_ReturnOutPut(OW, Text, FileName, 0)
	}

TF_RegExReplaceInLines(Text, StartLine = 1, EndLine = 0, NeedleRegEx = "", Replacement = "")
	{
	 options:="^[imsxADJUXPS]+\)" ; Hat tip to sinkfaze http://www.autohotkey.com/forum/viewtopic.php?t=60062
	 If RegExMatch(searchText,options,o)
		searchText := RegExReplace(searchText,options,(!InStr(o,"m") ? "m$0" : "$0"))
	 Else searchText := "m)" . searchText
	 TF_GetData(OW, Text, FileName)
		If (RegExMatch(Text, SearchText) < 1)
			Return Text ; SearchText not in TextFile so return and do nothing, we have to return Text in case of a variable otherwise it would empty the variable contents bug fix 3.3

	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 Loop, Parse, Text, `n, `r
		{
		 If A_Index in %TF_MatchList%
			{
			 LoopField := RegExReplace(A_LoopField, NeedleRegEx, Replacement)
			 OutPut .= LoopField "`n"
			}
		 Else
			OutPut .= A_LoopField "`n"
		}
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

TF_RegExReplace(Text, NeedleRegEx = "", Replacement = "")
	{
	 options:="^[imsxADJUXPS]+\)" ; Hat tip to sinkfaze http://www.autohotkey.com/forum/viewtopic.php?t=60062
	 if RegExMatch(searchText,options,o)
		searchText := RegExReplace(searchText,options,(!InStr(o,"m") ? "m$0" : "$0"))
	 else searchText := "m)" . searchText
	 TF_GetData(OW, Text, FileName)
		If (RegExMatch(Text, SearchText) < 1)
			Return Text ; SearchText not in TextFile so return and do nothing, we have to return Text in case of a variable otherwise it would empty the variable contents bug fix 3.3
	 Text := RegExReplace(Text, NeedleRegEx, Replacement)
	 Return TF_ReturnOutPut(OW, Text, FileName, 0)
	}

TF_RemoveLines(Text, StartLine = 1, EndLine = 0)
	{
	 TF_GetData(OW, Text, FileName)
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 Loop, Parse, Text, `n, `r
		{
		 If A_Index in %TF_MatchList%
			Continue
		 Else
			OutPut .= A_LoopField "`n"
		}
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

TF_RemoveBlankLines(Text, StartLine = 1, EndLine = 0)
	{
	 TF_GetData(OW, Text, FileName)
	 If (RegExMatch(Text, "[\S]+?\r?\n?") < 1)
	 	Return Text ; No empty lines so return and do nothing, we have to return Text in case of a variable otherwise it would empty the variable contents bug fix 3.3
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 Loop, Parse, Text, `n, `r
		{ 
		 If A_Index in %TF_MatchList%
			OutPut .= (RegExMatch(A_LoopField,"[\S]+?\r?\n?")) ? A_LoopField "`n" :
		 Else
			OutPut .= A_LoopField "`n"
		}
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

TF_RemoveDuplicateLines(Text, StartLine = 1, Endline = 0, Consecutive = 0, CaseSensitive = false)
	{
	 TF_GetData(OW, Text, FileName)
	 If (StartLine = "")
	 	StartLine = 1
	 If (Endline = 0 OR Endline = "")
	 	EndLine := TF_Count(Text, "`n") + 1
	 Loop, Parse, Text, `n, `r
		{
		 If (A_Index < StartLine)
			Section1 .= A_LoopField "`n"
		 If A_Index between %StartLine% and %Endline%
			{
			 If (Consecutive = 1)
				{
				 If (A_LoopField <> PreviousLine) ; method one for consecutive duplicate lines
					 Section2 .= A_LoopField "`n"
				 PreviousLine:=A_LoopField
				} 
			 Else
				{
				 If !(InStr(SearchForSection2,"__bol__" . A_LoopField . "__eol__",CaseSensitive)) ; not found
				 	{
				 	 SearchForSection2 .= "__bol__" A_LoopField "__eol__" ; this makes it unique otherwise it could be a partial match
					 Section2 .= A_LoopField "`n"
				 	}
				}	 
			}
		 If (A_Index > EndLine)
			Section3 .= A_LoopField "`n"
		}
	 Output .= Section1 Section2 Section3
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

TF_InsertLine(Text, StartLine = 1, Endline = 0, InsertText = "")
	{
	 TF_GetData(OW, Text, FileName)
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 Loop, Parse, Text, `n, `r
		{
		 If A_Index in %TF_MatchList%
			Output .= InsertText "`n" A_LoopField "`n"
		 Else 
			Output .= A_LoopField "`n"
		}
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

TF_ReplaceLine(Text, StartLine = 1, Endline = 0, ReplaceText = "")
	{
	 TF_GetData(OW, Text, FileName)
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 Loop, Parse, Text, `n, `r
		{
		 If A_Index in %TF_MatchList%
			Output .= ReplaceText "`n" 
		 Else 
			Output .= A_LoopField "`n"
		}
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

TF_InsertPrefix(Text, StartLine = 1, EndLine = 0, InsertText = "")
	{
	 TF_GetData(OW, Text, FileName)
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 Loop, Parse, Text, `n, `r
		{
		 If A_Index in %TF_MatchList%
			OutPut .= InsertText A_LoopField "`n"
		 Else
			OutPut .= A_LoopField "`n"
		}
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

TF_InsertSuffix(Text, StartLine = 1, EndLine = 0 , InsertText = "")
	{
	 TF_GetData(OW, Text, FileName)
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 Loop, Parse, Text, `n, `r
		{
		 If A_Index in %TF_MatchList%
			OutPut .= A_LoopField InsertText "`n"
		 Else
			OutPut .= A_LoopField "`n"
		}
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

TF_TrimLeft(Text, StartLine = 1, EndLine = 0, Count = 1)
	{
	 TF_GetData(OW, Text, FileName)
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 Loop, Parse, Text, `n, `r
		{
		 If A_Index in %TF_MatchList%
			{
			 StringTrimLeft, StrOutPut, A_LoopField, %Count%
			 OutPut .= StrOutPut "`n"
			}
		 Else
			OutPut .= A_LoopField "`n"
		}
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

TF_TrimRight(Text, StartLine = 1, EndLine = 0, Count = 1)
	{
	 TF_GetData(OW, Text, FileName)
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 Loop, Parse, Text, `n, `r
		{
		 If A_Index in %TF_MatchList%
			{
			 StringTrimRight, StrOutPut, A_LoopField, %Count%
			 OutPut .= StrOutPut "`n"
			}
		 Else
			OutPut .= A_LoopField "`n"
		}
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

TF_AlignLeft(Text, StartLine = 1, EndLine = 0, Columns = 80, Padding = 0)
	{
	 Trim:=A_AutoTrim ; store trim settings
	 AutoTrim, On ; make sure AutoTrim is on
	 TF_GetData(OW, Text, FileName)
	 If (Endline = 0 OR Endline = "")
		EndLine := TF_Count(Text, "`n") + 1
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 Loop, Parse, Text, `n, `r
		{
		 If A_Index in %TF_MatchList%
			{
			 LoopField = %A_LoopField% ; Make use of AutoTrim, should be faster then a RegExReplace. Trims leading and trailing spaces!
			 SpaceNum := Columns-StrLen(LoopField)-1 
			 If (SpaceNum > 0) and (Padding = 1) ; requires padding + keep padding
				{
				 Left:=TF_SetWidth(LoopField,Columns, 0) ; align left
				 OutPut .= Left "`n"
				}
			 Else 
				OutPut .= LoopField "`n"
			}
		 Else
		 	OutPut .= A_LoopField "`n"
		}
	 AutoTrim, %Trim%	; restore original Trim
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

TF_AlignCenter(Text, StartLine = 1, EndLine = 0, Columns = 80, Padding = 0)
	{
	 Trim:=A_AutoTrim ; store trim settings
	 AutoTrim, On ; make sure AutoTrim is on
	 TF_GetData(OW, Text, FileName)
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 Loop, Parse, Text, `n, `r
		{
		 If A_Index in %TF_MatchList%
			{
			 LoopField = %A_LoopField% ; Make use of AutoTrim, should be faster then a RegExReplace
			 SpaceNum := (Columns-StrLen(LoopField)-1)/2
			 If (Padding = 1) and (LoopField = "") ; skip empty lines, do not fill with spaces
				{
				 OutPut .= "`n"
				 Continue
				}
			 If (StrLen(LoopField) >= Columns)
				{
				 OutPut .= LoopField "`n" ; add as is 	
				 Continue
				}
			 Centered:=TF_SetWidth(LoopField,Columns, 1) ; align center using set width
			 OutPut .= Centered "`n"
			}
		 Else
			OutPut .= A_LoopField "`n"
		}
	 AutoTrim, %Trim%	; restore original Trim
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

TF_AlignRight(Text, StartLine = 1, EndLine = 0, Columns = 80, Skip = 0)
	{
	 Trim:=A_AutoTrim ; store trim settings
	 AutoTrim, On ; make sure AutoTrim is on
	 TF_GetData(OW, Text, FileName)
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 Loop, Parse, Text, `n, `r
		{
		 If A_Index in %TF_MatchList%
			{
			 LoopField = %A_LoopField% ; Make use of AutoTrim, should be faster then a RegExReplace
			 If (Skip = 1) and (LoopField = "") ; skip empty lines, do not fill with spaces
				{
				 OutPut .= "`n"
				 Continue
				}
			 If (StrLen(LoopField) >= Columns) 
				{
				 OutPut .= LoopField "`n" ; add as is 	
				 Continue
				}
			 Right:=TF_SetWidth(LoopField,Columns, 2) ; align right using set width
			 OutPut .= Right "`n"
			}
		 Else
			OutPut .= A_LoopField "`n"
		}
	 AutoTrim, %Trim%	; restore original Trim
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

; Based on: CONCATenate text files, ftp://garbo.uwasa.fi/pc/ts/tsfltc22.zip
TF_ConCat(FirstTextFile, SecondTextFile, OutputFile = "", Blanks = 0, FirstPadMargin = 0, SecondPadMargin = 0)
	{
	 If (Blanks > 0)
		Loop, %Blanks%
			InsertBlanks .= A_Space
	 If (FirstPadMargin > 0)
		Loop, %FirstPadMargin%
			PaddingFile1 .= A_Space
	 If (SecondPadMargin > 0)
		Loop, %SecondPadMargin%
	 		PaddingFile2 .= A_Space
	 Text:=FirstTextFile		
	 TF_GetData(OW, Text, FileName)
	 StringSplit, Str1Lines, Text, `n, `r
	 Text:=SecondTextFile
	 TF_GetData(OW, Text, FileName)
	 StringSplit, Str2Lines, Text, `n, `r
	 Text= ; clear mem

	 ; first we need to determine the file with the most lines for our loop
	 If (Str1Lines0 > Str2Lines0)
		MaxLoop:=Str1Lines0
	 Else
		MaxLoop:=Str2Lines0
	 Loop, %MaxLoop%
		{
		 Section1:=Str1Lines%A_Index%
		 Section2:=Str2Lines%A_Index%
		 OutPut .= Section1 PaddingFile1 InsertBlanks Section2 PaddingFile2 "`n"
		 Section1= ; otherwise it will remember the last line from the shortest file or var
		 Section2=
		}
	 OW=1 ; it is probably 0 so in that case it would create _copy, so set it to 1
	 If (OutPutFile = "") ; if OutPutFile is empty return as variable
		OW=2
	 Return TF_ReturnOutPut(OW, OutPut, OutputFile, 1, 1)
	}

TF_LineNumber(Text, Leading = 0, Restart = 0, Char = 0) ; HT ribbet.1
	{
	 global t
	 TF_GetData(OW, Text, FileName)
	 Lines:=TF_Count(Text, "`n") + 1
	 Padding:=StrLen(Lines)
	 If (Leading = 0) and (Char = 0)
		Char := A_Space
	 Loop, %Padding%
		PadLines .= Char
	 Loop, Parse, Text, `n, `r
		{
		 If Restart = 0
			MaxNo = %A_Index%
		 Else
			{
			 MaxNo++
			 If MaxNo > %Restart%
				MaxNo = 1
			}
		 LineNumber:= MaxNo
		 If (Leading = 1)
			{
			 LineNumber := Padlines LineNumber ; add padding
			 StringRight, LineNumber, LineNumber, StrLen(Lines) ; remove excess padding
			}
		 If (Leading = 0)
			{
			 LineNumber := LineNumber Padlines ; add padding
			 StringLeft, LineNumber, LineNumber, StrLen(Lines) ; remove excess padding
			} 
		 OutPut .= LineNumber A_Space A_LoopField "`n"
		}
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

; skip = 1, skip shorter lines (e.g. lines shorter startcolumn position)
; modified in TF 3.4, fixed in 3.5
TF_ColGet(Text, StartLine = 1, EndLine = 0, StartColumn = 1, EndColumn = 1, Skip = 0)
	{ 
	 TF_GetData(OW, Text, FileName)
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 If (StartColumn < 0)
	 	{
		 StartColumn++
		 Loop, Parse, Text, `n, `r ; parsing file/var
			{
			 If A_Index in %TF_MatchList% 
				{
				 output .= SubStr(A_LoopField,StartColumn) "`n"
				}
			 else
				 output .= A_LoopField "`n"
			}
	 	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	 	}
	 if RegExMatch(StartColumn, ",|\+|-") 
		{
		 StartColumn:=_MakeMatchList(Text, StartColumn, 1, 1)
		 Loop, Parse, Text, `n, `r ; parsing file/var
			{
			 If A_Index in %TF_MatchList% 
				{
				 loop, parse, A_LoopField ; parsing LINE char by char
					{
					 If A_Index in %StartColumn% ; if col in index get char
						output .= A_LoopField
					}
				 output .= "`n"
				}
			 else
				 output .= A_LoopField "`n"
			}
		 output .= A_LoopField "`n"
		}
	 else
		{
		 EndColumn:=(EndColumn+1)-StartColumn
		 Loop, Parse, Text, `n, `r
			{
			 If A_Index in %TF_MatchList%
				{
				 StringMid, Section, A_LoopField, StartColumn, EndColumn
				 If (Skip = 1) and (StrLen(A_LoopField) < StartColumn)
					Continue
				 OutPut .= Section "`n" 
				}
			}
		}	
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

; Based on: COLPUT.EXE & CUT.EXE, ftp://garbo.uwasa.fi/pc/ts/tsfltc22.zip
; modified in TF 3.4
TF_ColPut(Text, Startline = 1, EndLine = 0, StartColumn = 1, InsertText = "", Skip = 0)
	{ 
	 TF_GetData(OW, Text, FileName)
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 If RegExMatch(StartColumn, ",|\+") 
		{
		 StartColumn:=_MakeMatchList(Text, StartColumn, 0, 1)
		 Loop, Parse, Text, `n, `r ; parsing file/var
			{
			 If A_Index in %TF_MatchList% 
				{
				 loop, parse, A_LoopField ; parsing LINE char by char
					{
					 If A_Index in %StartColumn% ; if col in index insert text
						output .= InsertText A_LoopField
					 Else
						output .= A_LoopField 
					}
				 output .= "`n"
				}
			 else
				 output .= A_LoopField "`n"
			}
		 output .= A_LoopField "`n"
		}
	 else
		{
		 StartColumn--
		 Loop, Parse, Text, `n, `r
			{
			 If A_Index in %TF_MatchList%
				{
				 If (StartColumn > 0)
					{
					 StringLeft, Section1, A_LoopField, StartColumn
					 StringMid, Section2, A_LoopField, StartColumn+1
					 If (Skip = 1) and (StrLen(A_LoopField) < StartColumn)
						OutPut .= Section1 Section2 "`n"
					}
				 Else
					{
					 Section1:=SubStr(A_LoopField, 1, StrLen(A_LoopField) + StartColumn + 1)
					 Section2:=SubStr(A_LoopField, StrLen(A_LoopField) + StartColumn + 2)
					 If (Skip = 1) and (A_LoopField = "")
						OutPut .= Section1 Section2 "`n"
					}
				 OutPut .= Section1 InsertText Section2 "`n"	
				}
			 Else
				OutPut .= A_LoopField "`n"
			}
		}
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

; modified TF 3.4
TF_ColCut(Text, StartLine = 1, EndLine = 0, StartColumn = 1, EndColumn = 1)
	{
	 TF_GetData(OW, Text, FileName)
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 If RegExMatch(StartColumn, ",|\+|-") 
		{
		 StartColumn:=_MakeMatchList(Text, StartColumn, EndColumn, 1)
		 Loop, Parse, Text, `n, `r ; parsing file/var
			{
			 If A_Index in %TF_MatchList% 
				{
				 loop, parse, A_LoopField ; parsing LINE char by char
					{
					 If A_Index not in %StartColumn% ; if col not in index get char
						output .= A_LoopField
					}
				 output .= "`n"
				}
			 else
				 output .= A_LoopField "`n"
			}
		 output .= A_LoopField "`n"
		}
	 else
		{
		 StartColumn--
		 EndColumn++
		 Loop, Parse, Text, `n, `r
			{
			 If A_Index in %TF_MatchList%
				{
				 StringLeft, Section1, A_LoopField, StartColumn
				 StringMid, Section2, A_LoopField, EndColumn
				 OutPut .= Section1 Section2 "`n"
				}
			 Else
				OutPut .= A_LoopField "`n"
			}
		}	
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

TF_ReverseLines(Text, StartLine = 1, EndLine = 0)
	{
	 TF_GetData(OW, Text, FileName)
	 StringSplit, Line, Text, `n, `r ; line0 is number of lines
	 If (EndLine = 0 OR EndLine = "")
		EndLine:=Line0
	 If (EndLine > Line0)
		EndLine:=Line0
	 CountDown:=EndLine+1
	 Loop, Parse, Text, `n, `r
		{
		 If (A_Index < StartLine)
			Output1 .= A_LoopField "`n" ; section1
	 	 If A_Index between %StartLine% and %Endline%
			{
			 CountDown--
			 Output2 .= Line%CountDown% "`n" section2
			}
		 If (A_Index > EndLine)
			 Output3 .= A_LoopField "`n"
		}
	 OutPut.= Output1 Output2 Output3
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

;TF_SplitFileByLines
;example:
;TF_SplitFileByLines("TestFile.txt", "4", "sfile_", "txt", "1") ; split file every 3 lines
; InFile = 0 skip line e.g. do not include the actual line in any of the output files
; InFile = 1 include line IN current file
; InFile = 2 include line IN next file
TF_SplitFileByLines(Text, SplitAt, Prefix = "file", Extension = "txt", InFile = 1)
	{
	 LineCounter=1
	 FileCounter=1
	 Where:=SplitAt
	 Method=1 
	 ; 1 = default, splitat every X lines, 
	 ; 2 = splitat: - rotating if applicable 
	 ; 3 = splitat: specific lines comma separated
	 TF_GetData(OW, Text, FileName)
	 
	 IfInString, SplitAt, `- ; method 2
		{
		 StringSplit, Split, SplitAt, `-
		 Part=1
		 Where:=Split%Part%
		 Method=2
		} 
	 IfInString, SplitAt, `, ; method 3
		{
		 StringSplit, Split, SplitAt, `,
		 Part=1
		 Where:=Split%Part%
		 Method=3
		} 
	 Loop, Parse, Text, `n, `r
		{
		 OutPut .= A_LoopField "`n"
		 If (LineCounter = Where)
			{
			 If (InFile = 0)
				{
				 StringReplace, CheckOutput, PreviousOutput, `n, , All
				 StringReplace, CheckOutput, CheckOutput, `r, , All
				 If (CheckOutput <> "") and (OW <> 2) ; skip empty files
					TF_ReturnOutPut(1, PreviousOutput, Prefix FileCounter "." Extension, 0, 1) 
				 If (CheckOutput <> "") and (OW = 2) ; skip empty files
					 TF_SetGlobal(Prefix FileCounter,PreviousOutput)
		 		 Output:=
				}
			 If (InFile = 1)
				{
				 StringReplace, CheckOutput, Output, `n, , All
				 StringReplace, CheckOutput, CheckOutput, `r, , All
				 If (CheckOutput <> "") and (OW <> 2) ; skip empty files
				 	 TF_ReturnOutPut(1, Output, Prefix FileCounter "." Extension, 0, 1) 
				 If (CheckOutput <> "") and (OW = 2) ; skip empty files
				 	 TF_SetGlobal(Prefix FileCounter,Output)
				 Output:=
				}
			 If (InFile = 2)
				{
				 OutPut := PreviousOutput
				 StringReplace, CheckOutput, Output, `n, , All
				 StringReplace, CheckOutput, CheckOutput, `r, , All
				 If (CheckOutput <> "") and (OW <> 2) ; skip empty files
					 TF_ReturnOutPut(1, Output, Prefix FileCounter "." Extension, 0, 1) 
				 If (CheckOutput <> "") and (OW = 2) ; output to array
				 	 TF_SetGlobal(Prefix FileCounter,Output)
				 OutPut := A_LoopField "`n"
				}
			 If (Method <> 3)			
				 LineCounter=0 ; reset
			 FileCounter++ ; next file
			 Part++
			 If (Method = 2) ; 2 = splitat: - rotating if applicable 
			 	{
			 If (Part > Split0)
					{
					 Part=1
					}
				 Where:=Split%Part%
				}
			 If (Method = 3) ; 3 = splitat: specific lines comma separated
				{
				 If (Part > Split0)
					Where:=Split%Split0%
				 Else
					Where:=Split%Part%
				}
			}
		 LineCounter++
		 PreviousOutput:=Output
		 PreviousLine:=A_LoopField
		}
	 StringReplace, CheckOutput, Output, `n, , All
	 StringReplace, CheckOutput, CheckOutput, `r, , All
	 If (CheckOutPut <> "") and (OW <> 2) ; skip empty files
		TF_ReturnOutPut(1, Output, Prefix FileCounter "." Extension, 0, 1) 
	 If (CheckOutput <> "") and (OW = 2) ; output to array
		{
		 TF_SetGlobal(Prefix FileCounter,Output)
		 TF_SetGlobal(Prefix . "0" , FileCounter)
		} 
	}

; TF_SplitFileByText("TestFile.txt", "button", "sfile_", "txt") ; split file at every line with button in it, can be regexp
; InFile = 0 skip line e.g. do not include the actual line in any of the output files
; InFile = 1 include line IN current file
; InFile = 2 include line IN next file
TF_SplitFileByText(Text, SplitAt, Prefix = "file", Extension = "txt", InFile = 1)
	{
	 LineCounter=1
	 FileCounter=1
	 TF_GetData(OW, Text, FileName)
	 SplitPath, TextFile,, Dir
	 Loop, Parse, Text, `n, `r
		{
		 OutPut .= A_LoopField "`n"
		 FoundPos:=RegExMatch(A_LoopField, SplitAt)
		 If (FoundPos > 0)
			{
			 If (InFile = 0)
				{
				 StringReplace, CheckOutput, PreviousOutput, `n, , All
				 StringReplace, CheckOutput, CheckOutput, `r, , All
				 If (CheckOutput <> "") and (OW <> 2) ; skip empty files
					TF_ReturnOutPut(1, PreviousOutput, Prefix FileCounter "." Extension, 0, 1) 
				 If (CheckOutput <> "") and (OW = 2) ; output to array
					TF_SetGlobal(Prefix FileCounter,PreviousOutput)
				 Output:=
				}
			 If (InFile = 1)
				{
				 StringReplace, CheckOutput, Output, `n, , All
				 StringReplace, CheckOutput, CheckOutput, `r, , All
				 If (CheckOutput <> "") and (OW <> 2) ; skip empty files
					TF_ReturnOutPut(1, Output, Prefix FileCounter "." Extension, 0, 1) 
				 If (CheckOutput <> "") and (OW = 2) ; output to array
					TF_SetGlobal(Prefix FileCounter,Output)
				 Output:=
				}
			 If (InFile = 2)
				{
				 OutPut := PreviousOutput
				 StringReplace, CheckOutput, Output, `n, , All
				 StringReplace, CheckOutput, CheckOutput, `r, , All
				 If (CheckOutput <> "") and (OW <> 2) ; skip empty files
					TF_ReturnOutPut(1, Output, Prefix FileCounter "." Extension, 0, 1) 
				 If (CheckOutput <> "") and (OW = 2) ; output to array
					TF_SetGlobal(Prefix FileCounter,Output)
				 OutPut := A_LoopField "`n"
				}
		 	 LineCounter=0 ; reset
		 	 FileCounter++ ; next file
			}
		 LineCounter++
		 PreviousOutput:=Output
		 PreviousLine:=A_LoopField
		}
	 StringReplace, CheckOutput, Output, `n, , All
	 StringReplace, CheckOutput, CheckOutput, `r, , All
	 If (CheckOutPut <> "") and (OW <> 2) ; skip empty files
		TF_ReturnOutPut(1, Output, Prefix FileCounter "." Extension, 0, 1) 
	 If (CheckOutput <> "") and (OW = 2) ; output to array
		{
		 TF_SetGlobal(Prefix FileCounter,Output)
		 TF_SetGlobal(Prefix . "0" , FileCounter)
		} 
	}

TF_Find(Text, StartLine = 1, EndLine = 0, SearchText = "", ReturnFirst = 1, ReturnText = 0)
	{
	 options:="^[imsxADJUXPS]+\)"
	 if RegExMatch(searchText,options,o)
		searchText:=RegExReplace(searchText,options,(!InStr(o,"m") ? "m$0(*ANYCRLF)" : "$0"))
	 else searchText:="m)(*ANYCRLF)" searchText
	 options:="^[imsxADJUXPS]+\)" ; Hat tip to sinkfaze, see http://www.autohotkey.com/forum/viewtopic.php?t=60062
	 if RegExMatch(searchText,options,o)
		searchText := RegExReplace(searchText,options,(!InStr(o,"m") ? "m$0" : "$0"))
	 else searchText := "m)" . searchText

	 TF_GetData(OW, Text, FileName)
	 If (RegExMatch(Text, SearchText) < 1)
		Return "0" ; SearchText not in file or error, so do nothing

	 TF_GetData(OW, Text, FileName)
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 Loop, Parse, Text, `n, `r
		{
		 If A_Index in %TF_MatchList%
			{
			 If (RegExMatch(A_LoopField, SearchText) > 0)
				{
				 If (ReturnText = 0)
					Lines .= A_Index "," ; line number
				 Else If (ReturnText = 1)
					Lines .= A_LoopField "`n" ; text of line 
				 Else If (ReturnText = 2)
					Lines .= A_Index ": " A_LoopField "`n" ; add line number
				 If (ReturnFirst = 1) ; only return first occurrence
					Break
				}	
			}	
		}
	 If (Lines <> "")
		StringTrimRight, Lines, Lines, 1 ; trim trailing , or `n
	 Else
		Lines = 0 ; make sure we return 0
	 Return Lines
	}

TF_Prepend(File1, File2)
	{
FileList=
(
%File1%
%File2%
)
TF_Merge(FileList,"`n", "!" . File2)
Return
	}

TF_Append(File1, File2)
	{
FileList=
(
%File2%
%File1%
)
TF_Merge(FileList,"`n", "!" . File2)
Return
	}

; For TF_Merge You will need to create a Filelist variable, one file per line,
; to pass on to the function:
; FileList=
; (
; c:\file1.txt
; c:\file2.txt
; )
; use Loop (files & folders) to create one quickly if you want to merge all TXT files for example
;
; Loop, c:\*.txt
;   FileList .= A_LoopFileFullPath "`n"
;
; By default, a new line is used as a separator between two text files
; !merged.txt deletes target file before starting to merge files
TF_Merge(FileList, Separator = "`n", FileName = "merged.txt") 
	{
	 OW=0
	 Loop, Parse, FileList, `n, `r
		{
		 Append2File= ; Just make sure it is empty
		 IfExist, %A_LoopField%
			{
			 FileRead, Append2File, %A_LoopField%
			 If not ErrorLevel ; Successfully loaded
				Output .= Append2File Separator
			}
		}

	 If (SubStr(FileName,1,1)="!") ; check if we want to delete the target file before we start
		{
		 FileName:=SubStr(FileName,2)
		 OW=1	 
		}
	 Return TF_ReturnOutPut(OW, OutPut, FileName, 0, 1)
	}

TF_Wrap(Text, Columns = 80, AllowBreak = 0, StartLine = 1, EndLine = 0)
	{
	 TF_GetData(OW, Text, FileName)
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 If (AllowBreak = 1)
		Break=
	 Else
		Break=[ \r?\n]
	 Loop, Parse, Text, `n, `r
		{
		 If A_Index in %TF_MatchList%
			{
			 If (StrLen(A_LoopField) > Columns)
				{
				 LoopField := A_LoopField " " ; just seems to work better by adding a space
				 OutPut .= RegExReplace(LoopField, "(.{1," . Columns . "})" . Break , "$1`n")
				}
			 Else
				OutPut .= A_LoopField "`n"
			}	
		 Else
			 OutPut .= A_LoopField "`n"
		}		
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

TF_WhiteSpace(Text, RemoveLeading = 1, RemoveTrailing = 1, StartLine = 1, EndLine = 0) {
	 TF_GetData(OW, Text, FileName)
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList
	 Trim:=A_AutoTrim ; store trim settings
	 AutoTrim, On ; make sure AutoTrim is on
	 Loop, Parse, Text, `n, `r
		{
		 If A_Index in %TF_MatchList%
			{
			 If (RemoveLeading = 1) AND (RemoveTrailing = 1)
			 	{
				 LoopField = %A_LoopField%
				 Output .= LoopField "`n"
					 Continue
				}
			 If (RemoveLeading = 1) AND (RemoveTrailing = 0)
				{
				 LoopField := A_LoopField . "."
				 LoopField = %LoopField%
				 StringTrimRight, LoopField, LoopField, 1
				 Output .= LoopField "`n"
					 Continue
				}
			 If (RemoveLeading = 0) AND (RemoveTrailing = 1)
				{
				 LoopField := "." A_LoopField
				 LoopField = %LoopField%
				 StringTrimLeft, LoopField, LoopField, 1
				 Output .= LoopField "`n"
					 Continue
				}
			 If (RemoveLeading = 0) AND (RemoveTrailing = 0)
				{
				 Output .= A_LoopField "`n"
					 Continue
				}
			}
		 Else
			Output .= A_LoopField "`n"
		}
	AutoTrim, %Trim%	; restore original Trim
	Return TF_ReturnOutPut(OW, OutPut, FileName)
}

; Delete lines from file1 in file2 (using StringReplace)
; Partialmatch = 2 added in 3.4
TF_Substract(File1, File2, PartialMatch = 0) {
	Text:=File1
	TF_GetData(OW, Text, FileName)
	Str1:=Text
	Text:=File2
	TF_GetData(OW, Text, FileName)
		OutPut:=Text
	If (OW = 2)
		File1= ; free mem in case of var/text
	OutPut .= "`n" ; just to make sure the StringReplace will work

	If (PartialMatch = 2)
		{
		 Loop, Parse, Str1, `n, `r
			{
			 IfInString, Output, %A_LoopField%
			 	{
				 Output:= RegExReplace(Output, "im)^.*" . A_LoopField . ".*\r?\n?", replace)
			 	}	
			}
		}
	Else If (PartialMatch = 1) ; allow paRTIal match
		{
		 Loop, Parse, Str1, `n, `r
		 	StringReplace, Output, Output, %A_LoopField%, , All ; remove lines from file1 in file2
		}
	Else If (PartialMatch = 0)
		{ 
		 search:="m)^(.*)$"
		 replace=__bol__$1__eol__
		 Output:=RegExReplace(Output, search, replace)
		 StringReplace, Output, Output, `n__eol__,__eol__ , All ; strange fix but seems to be needed.
		 Loop, Parse, Str1, `n, `r
			StringReplace, Output, Output, __bol__%A_LoopField%__eol__, , All ; remove lines from file1 in file2
		}	
	If (PartialMatch = 0)
		{
		 StringReplace, Output, Output, __bol__, , All
		 StringReplace, Output, Output, __eol__, , All
		}
		
	; Remove all blank lines from the text in a variable:
	Loop
		{
		 StringReplace, Output, Output, `r`n`r`n, `r`n, UseErrorLevel
		 if (ErrorLevel = 0) or (ErrorLevel = 1) ; No more replacements needed.
			break
		}	
	Return TF_ReturnOutPut(OW, OutPut, FileName, 0)
}

; Similar to "BK Replace EM" RangeReplace
TF_RangeReplace(Text, SearchTextBegin, SearchTextEnd, ReplaceText = "", CaseSensitive = "False", KeepBegin = 0, KeepEnd = 0)
	{
	 TF_GetData(OW, Text, FileName)
	 IfNotInString, Text, %SearchText%
		Return Text ; SearchTextBegin not in TextFile so return and do nothing, we have to return Text in case of a variable otherwise it would empty the variable contents bug fix 3.3
	 Start = 0
	 End = 0
	 If (KeepBegin = 1)
	 	 KeepBegin:=SearchTextBegin
	 Else
		 KeepBegin=
	 If (KeepEnd = 1)
	 	 KeepEnd:= SearchTextEnd
	 Else
		 KeepEnd=
	 If (SearchTextBegin = "")
	 	 Start=1
	 If (SearchTextEnd = "")
	 	 End=2
	
	 Loop, Parse, Text, `n, `r
		{
		 If (End = 1) ; end has been found already, replacement made simply continue to add all lines
			{
			 Output .= A_LoopField "`n"
				 Continue
			}
		 If (Start = 0) ; start hasn't been found
			{
			 If (InStr(A_LoopField,SearchTextBegin,CaseSensitive)) ; start has been found
				{
				 Start = 1
				 KeepSection := SubStr(A_LoopField, 1, InStr(A_LoopField, SearchTextBegin)-1) 
				 EndSection := SubStr(A_LoopField, InStr(A_LoopField, SearchTextBegin)-1) 
				 ; check if SearchEndText is in second part of line
				 If (InStr(EndSection,SearchTextEnd,CaseSensitive)) ; end found
					{
					 EndSection := ReplaceText KeepEnd SubStr(EndSection, InStr(EndSection, SearchTextEnd) + StrLen(SearchTextEnd) ) "`n"
					 If (End <> 2)	
					 	End=1
					 If (End = 2)	
					 	EndSection=
					}
				 Else
					EndSection=
				 Output .= KeepSection KeepBegin EndSection
				 Continue
				}
			 Else	
				Output .= A_LoopField "`n" ; if not found yet simply add
				}
		 If (Start = 1) and (End <> 2) ; start has been found, now look for end if end isn't an empty string
			{
			 If (InStr(A_LoopField,SearchTextEnd,CaseSensitive)) ; end found
				{
				 End = 1
				 Output .= ReplaceText KeepEnd SubStr(A_LoopField, InStr(A_LoopField, SearchTextEnd) + StrLen(SearchTextEnd) ) "`n"
				}
			}
		} 
	 If (End = 2)	
	 	Output .= ReplaceText
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

; Create file of X lines and Y columns, fill with space or other character(s)
TF_MakeFile(Text, Lines = 1, Columns = 1, Fill = " ")
	{
	 OW=1
	 If (Text = "") ; if OutPutFile is empty return as variable
		OW=2
	 Loop, % Columns
		Cols .= Fill
	 Loop, % Lines
		Output .= Cols "`n"
	 Return TF_ReturnOutPut(OW, OutPut, Text, 1, 1)	
	}

; Convert tabs to spaces, shorthand for TF_ReplaceInLines
TF_Tab2Spaces(Text, TabStop = 4, StartLine = 1, EndLine =0)
	{
	Loop, % TabStop
		Replace .= A_Space
	Return TF_ReplaceInLines(Text, StartLine, EndLine, A_Tab, Replace)
	}

; Convert spaces to tabs, shorthand for TF_ReplaceInLines
TF_Spaces2Tab(Text, TabStop = 4, StartLine = 1, EndLine =0)
	{
	Loop, % TabStop
		Replace .= A_Space
	Return TF_ReplaceInLines(Text, StartLine, EndLine, Replace, A_Tab)
	}

; Sort (section of) a text file
TF_Sort(Text, SortOptions = "", StartLine = 1, EndLine = 0) ; use the SORT options http://www.autohotkey.com/docs/commands/Sort.htm
	{
	 TF_GetData(OW, Text, FileName)
	 If StartLine contains -,+,`, ; no sections, incremental or multiple line input
		Return
	 If (StartLine = 1) and (Endline = 0) ; process entire file
		{
		 Output:=Text
		 Sort, Output, %SortOptions%
		}
	 Else
		{
		 Output := TF_ReadLines(Text, 1, StartLine-1) ; get first section
		 ToSort := TF_ReadLines(Text, StartLine, EndLine) ; get section to sort
		 Sort, ToSort, %SortOptions%
		 OutPut .= ToSort
		 OutPut .= TF_ReadLines(Text, EndLine+1) ; append last section
		} 
	 Return TF_ReturnOutPut(OW, OutPut, FileName)
	}

TF_Tail(Text, Lines = 1, RemoveTrailing = 0, ReturnEmpty = 1)
	{
	 TF_GetData(OW, Text, FileName)
	 Neg = 0
	 If (Lines < 0)
		{
		 Neg=1
		 Lines:= Lines * -1
		}
	 If (ReturnEmpty = 0) ; remove blank lines first so we can't return any blank lines anyway
		{
		 Loop, Parse, Text, `n, `r
			OutPut .= (RegExMatch(A_LoopField,"[\S]+?\r?\n?")) ? A_LoopField "`n" :
		 StringTrimRight, OutPut, OutPut, 1 ; remove trailing `n added by loop above
		 Text:=OutPut
		 OutPut=
	}
	 If (Neg = 1) ; get only one line!
		{ 
		 Lines++
		 Output:=Text
		 StringGetPos, Pos, Output, `n, R%Lines% ; These next two Lines by Tuncay see
		 StringTrimLeft, Output, Output, % ++Pos ; http://www.autoHotkey.com/forum/viewtopic.php?p=262375#262375
		 StringGetPos, Pos, Output, `n
		 StringLeft, Output, Output, % Pos
		 Output .= "`n"
		}
	 Else
		{
		 Output:=Text
		 StringGetPos, Pos, Output, `n, R%Lines% ; These next two Lines by Tuncay see
		 StringTrimLeft, Output, Output, % ++Pos ; http://www.autoHotkey.com/forum/viewtopic.php?p=262375#262375
		 Output .= "`n"
		}
	 OW = 2 ; make sure we return variable not process file
	 Return TF_ReturnOutPut(OW, OutPut, FileName, RemoveTrailing)
	}

TF_Count(String, Char)
	{
	StringReplace, String, String, %Char%,, UseErrorLevel
	Return ErrorLevel
	}

TF_Save(Text, FileName, OverWrite = 1) { ; HugoV write file
	Return TF_ReturnOutPut(OverWrite, Text, FileName, 0, 1)
	}

TF(TextFile, CreateGlobalVar = "T") { ; read contents of file in output and %output% as global var ...  http://www.autohotkey.com/forum/viewtopic.php?p=313120#313120
	 global
	 FileRead, %CreateGlobalVar%, %TextFile%
	 Return, (%CreateGlobalVar%)
	}

; TF_Join
; SmartJoin: Detect if CHAR(s) is/are already present at the end of the line before joining the next, this to prevent unnecessary double spaces for example.
; Char: character(s) to use between new lines, defaults to a space. To use nothing use ""
TF_Join(Text, StartLine = 1, EndLine = 0, SmartJoin = 0, Char = 0)
	{
	 If ( (InStr(StartLine,",") > 0) AND (InStr(StartLine,"-") = 0) ) OR (InStr(StartLine,"+") > 0)
		Return Text ; can't do multiplelines, only multiple sections of lines e.g. "1,5" bad "1-5,15-10" good, "2+2" also bad
	 TF_GetData(OW, Text, FileName) 
	 If (InStr(Text,"`n") = 0)
		Return Text ; there are no lines to join so just return Text
	 If (InStr(StartLine,"-") > 0)	; OK, we need some counter-intuitive string mashing to substract ONE from the "endline" parameter
		{
		 Loop, Parse, StartLine, CSV
			{
			 StringSplit, part, A_LoopField, -
			 NewStartLine .= part1 "-" (part2-1) ","
			}
		 StringTrimRight, StartLine, NewStartLine, 1
		}		
	 If (Endline > 0)
		Endline-- 
	 TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc)
	 If (Char = 0)
		Char:=A_Space
	 Char_Org:=Char
	 GetRightLen:=StrLen(Char)-1
	 Loop, Parse, Text, `n, `r
		{
		 If A_Index in %TF_MatchList%
			{
			 If (SmartJoin = 1)
				{
				 GetRightText:=SubStr(A_LoopField,0)
				 If (GetRightText = Char)
					Char=
				}
			 Output .= A_LoopField Char
			 Char:=Char_Org
			}
		 Else 
			Output .= A_LoopField "`n"
		}
	 Return TF_ReturnOutPut(OW, OutPut, FileName) 
	}

;----- Helper functions ----------------
	
TF_SetGlobal(var, content = "") ; helper function for TF_Split* to return array and not files, credits Tuncay :-)
	{
	 global
	 %var% := content
	}
	
; Helper function to determine if VAR/TEXT or FILE is passed to TF
; Update 11 January 2010 (skip filecheck if `n in Text -> can't be file)
TF_GetData(byref OW, byref Text, byref FileName) 
	{
	 If (text = 0) ; v3.6 
		{
		 MsgBox, 48, TF Lib Error, % "Read Error:`npossible reason: perhaps you used ! vs ""!"" ?"
		 ExitApp
		}
	 OW=0 ; default setting: asume it is a file and create file_copy
	 IfNotInString, Text, `n ; it can be a file as the Text doesn't contact a newline character
		{
		 If (SubStr(Text,1,1)="!") ; first we check for "overwrite" 
			{
			 Text:=SubStr(Text,2)
			 OW=1 ; overwrite file (if it is a file)
			} 
		 IfNotExist, %Text% ; now we can check if the file exists, it doesn't so it is a var
			{
			 If (OW=1) ; the variable started with a ! so we need to put it back because it is variable/text not a file
				Text:= "!" . Text
			 OW=2 ; no file, so it is a var or Text passed on directly to TF
			}
		}
	 Else ; there is a newline character in Text so it has to be a variable 
		{
		 OW=2
		}
	 If (OW = 0) or (OW = 1) ; it is a file, so we have to read into var Text
		{
		 Text := (SubStr(Text,1,1)="!") ? (SubStr(Text,2)) : Text
		 FileName=%Text% ; Store FileName
		 FileRead, Text, %Text% ; Read file and return as var Text
		 If (ErrorLevel > 0)
			{
			 MsgBox, 48, TF Lib Error, % "Can not read " FileName
			 ExitApp
			}
		}
	 Return
	}
	
; Skan - http://www.autohotkey.com/forum/viewtopic.php?p=45880#45880
; SetWidth() : SetWidth increases a String's length by adding spaces to it and aligns it Left/Center/Right. ( Requires Space() ) 
TF_SetWidth(Text,Width,AlignText)
	{
	 If (AlignText!=0 and AlignText!=1 and AlignText!=2)
		AlignText=0
	 If AlignText=0
		{
		 RetStr= % (Text)TF_Space(Width)
		 StringLeft, RetText, RetText, %Width%
		}
	 If AlignText=1 
		{
		 Spaces:=(Width-(StrLen(Text)))
		 RetStr= % TF_Space(Round(Spaces/2))(Text)TF_Space(Spaces-(Round(Spaces/2)))
		}
	 If AlignText=2
		{
		 RetStr= % TF_Space(Width)(Text)
		 StringRight, RetStr, RetStr, %Width%
		}
	 Return RetStr
	}

; Skan - http://www.autohotkey.com/forum/viewtopic.php?p=45880#45880
TF_Space(Width)
	{
	 Loop,%Width%
	 	Space=% Space Chr(32)
	 Return Space
	}

; Write to file or return variable depending on input
TF_ReturnOutPut(OW, Text, FileName, TrimTrailing = 1, CreateNewFile = 0) {
	If (OW = 0) ; input was file, file_copy will be created, if it already exist file_copy will be overwritten
		{
		 IfNotExist, % FileName ; check if file Exist, if not return otherwise it would create an empty file. Thanks for the idea Murp|e
			{
			 If (CreateNewFile = 1) ; CreateNewFile used for TF_SplitFileBy* and others
				{
				 OW = 1 
				 Goto CreateNewFile
				}
			 Else 
				Return
			}
		 If (TrimTrailing = 1)
			 StringTrimRight, Text, Text, 1 ; remove trailing `n
		 SplitPath, FileName,, Dir, Ext, Name
		 If (Dir = "") ; if Dir is empty Text & script are in same directory
			Dir := A_WorkingDir
		 IfExist, % Dir "\backup" ; if there is a backup dir, copy original file there
			FileCopy, % Dir "\" Name "_copy." Ext, % Dir "\backup\" Name "_copy.bak", 1
		 FileDelete, % Dir "\" Name "_copy." Ext
		 FileAppend, %Text%, % Dir "\" Name "_copy." Ext
		 Return Errorlevel ? False : True
		}
	 CreateNewFile:	
	 If (OW = 1) ; input was file, will be overwritten by output 
		{
		 IfNotExist, % FileName ; check if file Exist, if not return otherwise it would create an empty file. Thanks for the idea Murp|e
			{
			If (CreateNewFile = 0) ; CreateNewFile used for TF_SplitFileBy* and others
				Return
			}
		 If (TrimTrailing = 1)
			 StringTrimRight, Text, Text, 1 ; remove trailing `n
		 SplitPath, FileName,, Dir, Ext, Name
		 If (Dir = "") ; if Dir is empty Text & script are in same directory
			Dir := A_WorkingDir
		 IfExist, % Dir "\backup" ; if there is a backup dir, copy original file there
			FileCopy, % Dir "\" Name "." Ext, % Dir "\backup\" Name ".bak", 1
		 FileDelete, % Dir "\" Name "." Ext
		 FileAppend, %Text%, % Dir "\" Name "." Ext
		 Return Errorlevel ? False : True
		}
	If (OW = 2) ; input was var, return variable 
		{
		 If (TrimTrailing = 1)
			StringTrimRight, Text, Text, 1 ; remove trailing `n
		 Return Text
		}
	}

; _MakeMatchList()
; Purpose:
; Make a MatchList which is used in various functions
; Using a MatchList gives greater flexibility so you can process multiple
; sections of lines in one go avoiding repetitive fileread/append actions
; For TF 3.4 added COL = 0/1 option (for TF_Col* functions) and CallFunc for
; all TF_* functions to facilitate bug tracking
_MakeMatchList(Text, Start = 1, End = 0, Col = 0, CallFunc = "Not available")
	{
	 ErrorList=
	 (join|
Error 01: Invalid StartLine parameter (non numerical character)`nFunction used: %CallFunc%
Error 02: Invalid EndLine parameter (non numerical character)`nFunction used: %CallFunc%
Error 03: Invalid StartLine parameter (only one + allowed)`nFunction used: %CallFunc%
	 )
	 StringSplit, ErrorMessage, ErrorList, |
	 Error = 0

	 If (Col = 1)
		{
		 LongestLine:=TF_Stat(Text)
		 If (End > LongestLine) or (End = 1) ; FIXITHERE BUG
			End:=LongestLine
		}

	 TF_MatchList= ; just to be sure
	 If (Start = 0 or Start = "")
		Start = 1
		
	 ; some basic error checking

	 ; error: only digits - and + allowed
	 If (RegExReplace(Start, "[ 0-9+\-\,]", "") <> "")
		 Error = 1
		 
	 If (RegExReplace(End, "[0-9 ]", "") <> "")
		 Error = 2

	 ; error: only one + allowed
	 If (TF_Count(Start,"+") > 1)
		 Error = 3

	 If (Error > 0 )
		{
		 MsgBox, 48, TF Lib Error, % ErrorMessage%Error%
		 ExitApp
		}

	 ; Option #0 [ added 30-Oct-2010 ]
	 ; Startline has negative value so process X last lines of file
	 ; endline parameter ignored 

	 If (Start < 0) ; remove last X lines from file, endline parameter ignored
		{
		 Start:=TF_CountLines(Text) + Start + 1
		 End=0 ; now continue
		}

	 ; Option #1
	 ; StartLine has + character indicating startline + incremental processing. 
	 ; EndLine will be used
	 ; Make TF_MatchList

	 IfInString, Start, `+ 
		{
		 If (End = 0 or End = "") ; determine number of lines
			End:= TF_Count(Text, "`n") + 1
		 StringSplit, Section, Start, `, ; we need to create a new "TF_MatchList" so we split by ,
		 Loop, %Section0%
			{
			 StringSplit, SectionLines, Section%A_Index%, `+
			 LoopSection:=End + 1 - SectionLines1
			 Counter=0
			 	 TF_MatchList .= SectionLines1 ","
			 Loop, %LoopSection%
				{
				 If (A_Index >= End) ; 
					Break
				 If (Counter = (SectionLines2-1)) ; counter is smaller than the incremental value so skip
					{
					 TF_MatchList .= (SectionLines1 + A_Index) ","
					 Counter=0
					}
				 Else
					Counter++
				}
			}
		 StringTrimRight, TF_MatchList, TF_MatchList, 1 ; remove trailing , 
		 Return TF_MatchList
		}

	 ; Option #2
	 ; StartLine has - character indicating from-to, COULD be multiple sections. 
	 ; EndLine will be ignored
	 ; Make TF_MatchList

	 IfInString, Start, `-
		{
		 StringSplit, Section, Start, `, ; we need to create a new "TF_MatchList" so we split by ,
		 Loop, %Section0%
			{
			 StringSplit, SectionLines, Section%A_Index%, `-
			 LoopSection:=SectionLines2 + 1 - SectionLines1
			 Loop, %LoopSection%
				{
				 TF_MatchList .= (SectionLines1 - 1 + A_Index) ","
				}
			}
		 StringTrimRight, TF_MatchList, TF_MatchList, 1 ; remove trailing ,
		 Return TF_MatchList
		}

	 ; Option #3
	 ; StartLine has comma indicating multiple lines. 
	 ; EndLine will be ignored
	 
	 IfInString, Start, `,
		{
		 TF_MatchList:=Start
		 Return TF_MatchList
		}

	 ; Option #4
	 ; parameters passed on as StartLine, EndLine. 
	 ; Make TF_MatchList from StartLine to EndLine

	 If (End = 0 or End = "") ; determine number of lines
			End:= TF_Count(Text, "`n") + 1
	 LoopTimes:=End-Start
	 Loop, %LoopTimes%
		{
		 TF_MatchList .= (Start - 1 + A_Index) ","
		}
	 TF_MatchList .= End ","
	 StringTrimRight, TF_MatchList, TF_MatchList, 1 ; remove trailing ,
	 Return TF_MatchList
	}

; added for TF 3.4 col functions - currently only gets longest line may change in future
TF_Stat(Text)
	{ 
	 TF_GetData(OW, Text, FileName)	 
	 Sort, Text, f _AscendingLinesL
	 Pos:=InStr(Text,"`n")-1
	 Return pos
	}

_AscendingLinesL(a1, a2) ; used by TF_Stat
	{
	 Return StrLen(a2) - StrLen(a1)
	}

/* -------------- */

#include tf.ahk
msg =
(
123
456
789
000000
)
TF_RemoveLines(msg, 1,3)
MsgBox % msg
Win10x64, AHK v1.1.25

186

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

MsgBox % RegExReplace(msg, "^[^\n]+\n[^\n]+\n[^\n]+\n...", "")

187

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

mozers, спасибо! Но если сместить четвертую строку на пятую, оставив четвертую пустой, то удаление символов переходит на пятую строку.

Win10x64, AHK v1.1.25

188 (изменено: mozers, 2017-04-06 13:53:22)

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

becauseim, правильно формулируй условие (включая все возможные варианты).

RegExReplace(msg, "^.*(...)$", "$1")

Так - тупо 3 последних символа. Хотя так можно и вообще без регулярки. Что надо?

189

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

mozers, последние три не нужно, нужно убрать именно с начала четвертой строки и только три символа. Сейчас же остаются три символа с конца текста.

Также хотелось бы иметь возможность изменить сценарий таким образом, чтобы удалялись не три, а четыре строки с начала текста, а также, например, пять, а не три символов с восьмой, а не четвертой строки.

При абсолютном отсутствии понимания таких выражений, мне было бы лучше, наверное, использовать упомянутую выше библиотеку с фнкциями, но и с ней у меня возникли сложности.

Win10x64, AHK v1.1.25

190

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

Этот ваш, извините за прямоту, набор слов я понял так: "Удалить все начальные строки и 3 первых символа последней строки".

MsgBox % RegExReplace(msg, "^([^\n]+\n)+...", "")

Не так? Формулируйте четко.

191

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

mozers, переход строки может быть и \r и \n\r.

192 (изменено: mozers, 2017-04-06 16:43:36)

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

Malcev, неправда Ваша - \r\n А редчайший случай с \r - да - не ловит. Но у нас же винда а не никсы...

193 (изменено: becauseim, 2017-04-06 17:13:06)

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

mozers, теперь результат тот же, что и в первом Вашем примере. Символы съедаются на пятой строке.
И по-прежнему, не понимаю, как изменить данное выражение под другие значения.

Имеется в виду конткретная строка, в данном случае, четвертая. Т.е.  при таком исходном тексте MsgBox должен содержать все имеющиеся в тексте нули, т.к. четвертая строка пуста:

msg =
(
123
456
789

000000
)

Если с помощью регулярных выражений нельзя обозначать порядковый номер строки для редактирования, так и скажите, т.к. я не знаю.

Win10x64, AHK v1.1.25

194

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

mozers
Вообще-то есть \R. Но не суть. Задача не решена. Написано, что нужно удалить n-ое число начальных строк + 3 первые символа у n-ой строки. Т.е. промежуточные строки (в т.ч. пустые) должны остаться.

195 (изменено: Malcev, 2017-04-06 17:16:54)

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

mozers пишет:

Malcev, неправда Ваша - \r\n

Официально да. Но может же в принципе быть и \n\r:

msgbox Malcev`n`rнеправда Ваша - \r\n

196 (изменено: mozers, 2017-04-06 18:24:01)

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

Уже двое пытаются изложить ТЗ. Убейте меня - я не понимаю что надо.

RegExReplace(msg, "^([^\n]*?\n){3}...", "")

Так? Если - нет - я сдаюсь - телепатия кончилась.

197

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

mozers
Проще проигнорировать, если конкретика неясна. Лично я всё понял.

198

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

becauseim, если RegEx не нужен (и тут я абсолютно с вами согласен), тогда зачем постить в эту тему?
Сами нарываетесь на решения, в которые не врубитесь.
Напишите в тему TF, или заведите новую.

199 (изменено: Malcev, 2017-04-06 21:00:56)

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

msg =
(
123
456
789

000000
)
msgbox % RegexReplace(msg, "(.*?\R){3}([^\r\n]{0,3})\R?")

200

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

Неа:

msg =
(
123
456
789
333xxx


135264
)