1

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

Есть очень длинная строка, пример:

{"2":131075,"3":[null,2,"http://zen.yandex.ru/id/5d45990f32335400ae93"],"6":1,"24":"http://zen.yandex.ru/id/5d45990f32335400ae93"},
{"2":3,"3":{"1":3,"3":43683.45867068287},"6":0},{"2":3,"3":[null,2,"@dfgdfg"],"6":1},
{"2":131075,"3":[null,2,"http://zen.yandex.ru/id/5d45b92b5ba2b500adc24"],"6":1,"24":"http://zen.yandex.ru/id/5d45b92b5ba2b500adc24"},
{"2":3,"3":{"1":3,"3":43683.734845914354},"6":0},{"2":3,"3":[null,2,"@dfgdfg"],"6":1},
{"2":131075,"3":[null,2,"https://zen.yandex.ru/id/5a7ab3f057906a5f99887"],"6":1,"24":"https://zen.yandex.ru/id/5a7ab3f057906a5f99887"},
{"2":3,"3":{"1":3,"3":43683.74911434027},"6":0},{"2":3,"3":[null,2,"@fgdfdg"],"6":1},{"

Мне нужно загнать в массив все ссылки https://zen.yandex.ru/id/и.т.д.
Вот что я написал:

HelpReg = O)null,2,"(.*)"],"6":1,"24"
while RegExMatch( html, HelpReg , tempdate, A_Index = 1 ? 1 : tempdate.Pos(1) + tempdate.Len(1) )
   datelist.Push(price[1])

for k, v in datelist
   MsgBox, % v

Уверен что, что-то не так с регулярным выражением, просьба помочь и желательно избежать дублирования ссылок.

2

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

sememix пишет:

Мне нужно загнать в массив все ссылки https://zen.yandex.ru/id/и.т.д.

Только с https ?

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

3

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

teadrinker, и то, и то. Не очень понимаю как это реализовать.

4

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

Если не имеет значения, что находится перед и после, то так:

str = 
(
{"2":131075,"3":[null,2,"http://zen.yandex.ru/id/5d45990f32335400ae93"],"6":1,"24":"http://zen.yandex.ru/id/5d45990f32335400ae93"},
{"2":3,"3":{"1":3,"3":43683.45867068287},"6":0},{"2":3,"3":[null,2,"@dfgdfg"],"6":1},
{"2":131075,"3":[null,2,"http://zen.yandex.ru/id/5d45b92b5ba2b500adc24"],"6":1,"24":"http://zen.yandex.ru/id/5d45b92b5ba2b500adc24"},
{"2":3,"3":{"1":3,"3":43683.734845914354},"6":0},{"2":3,"3":[null,2,"@dfgdfg"],"6":1},
{"2":131075,"3":[null,2,"https://zen.yandex.ru/id/5a7ab3f057906a5f99887"],"6":1,"24":"https://zen.yandex.ru/id/5a7ab3f057906a5f99887"},
{"2":3,"3":{"1":3,"3":43683.74911434027},"6":0},{"2":3,"3":[null,2,"@fgdfdg"],"6":1},{"
)

links := {}, match := ""
while RegExMatch(str, "O)https?://zen.yandex.ru/id/[^""]*", match, match ? match.Pos + match.Len : 1)
   links[ match[0] ] := ""

for k in links
   MsgBox, % k
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5

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

Можно ли задать шаблон, который за один раз снимет обрамление кавычками из нескольких переменных? См. «text|name» —


text := """text"""
name := """name"""
all  := RegExReplace(text|name, "^""(.*)""$", "$1")
msgbox % all

6

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

Задать можно, но сам шаблон ничего не делает, придётся ещё функцию написать для него.

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

7 (изменено: DD, 2019-08-10 14:32:24)

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

По какой причине случайное значение дублируется во всех соответствиях шаблону? Как задать однократную обработку — согласно шаблону, с последующим обновлением и поиском сначала? То есть, чтобы произошёл захват двух первых соответствующих чисел, с вставкой после них двух одинаковых рандомных значений, а в последующем чтобы этот рандом менялся?

txt =
(
§1
§2
§1
§2
§1
§2
§3
)
Random, rand_mc, 10545530, 99453649
Random, rand_ss, 000, 999
r_num := rand_ss rand_mc
txt := RegExReplace(txt, "s)§(\d)(.*?\R.*?§)\1", "§$1[[" rand_mc "]]$2$1@" rand_mc "@")
rand_mc := ""
MsgBox % txt

8

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

Иначе говоря, сейчас шаблон обрабатывает все соответствия разом, как будто это в цикле происходит — а как останавливаться после первой обработки и повторять сначала?

9

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

Я, например, ничего не понял.

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

10

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

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


§1[[27705425]]
§2
§1@27705425@
§2[[27705425]]
§1
§2@27705425@
§3

А нужен такой (с разной парой рандомов) —


§1[[27705425]]
§2
§1@27705425@
§2[[99999999]]
§1
§2@99999999@
§3

11

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

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

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

12 (изменено: DD, 2019-08-10 22:22:26)

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

Наоборот за один проход это делается сейчас, а надо чтобы шаблон находил первую пару, обрабатывал ее по условию и начинал сначала. То есть, сколько бы не находилось соответствий в тексте, шаблон

txt := RegExReplace(txt, "s)§(\d)(.*?\R.*?§)\1", "§$1[[" rand_mc "]]$2$1@" rand_mc "@")

все их обработает разом, а надо остановиться на первом. Чтобы нашёл от цифры до такой же цифры, обработал — и обратно)). Может, для этого RegExReplace не подходит?

13

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

Я имел в виду, что в один RegExReplace это упаковать нельзя, можно только в цикле.

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

14

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

Это бы не имело значения.

15

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

Так тоже всё разом обрабатывается —

text =
(
§1
§2
§1
§2
§1
§2
§3
)

Pos := 1
While Pos := RegExMatch(text, "s)§(\d)(.*?\R.*?§)\1",sentence,Pos+StrLen(sentence))
{
   Random, r_num, 10545530, 99453649
   sentence := RegExReplace(text, "s)§(\d)(.*?\R.*?§)\1", "§$1[[" r_num "]]$2$1@" r_num "@")
   r_num := ""
   MsgBox % sentence
}

16 (изменено: teadrinker, 2019-08-12 15:31:02)

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

text =
(
§1
§2
§1
§2
§1
§2
§3
)

p := "sU)(§\d)(.*\R.*\1)", m := ""
While RegExMatch(text, "O" . p, m, m ? m.Pos + m.Len + StrLen(r_num)*2 + 7 : 1)
{
   Random, r_num, 10545530, 99453649
   text := RegExReplace(text, p, "$1[[" r_num "]]$2@" r_num "@",, 1, m.Pos)
}
MsgBox % text
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder
+ DD

17

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

teadrinker пишет:

в один RegExReplace это упаковать нельзя, можно только в цикле.

А если через Regex Callouts?

18

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

Наверно можно, но семантически неверно. Regex Callouts создан для дебаггинга.

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

19 (изменено: Malcev, 2019-08-12 16:59:01)

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

Вроде вот так получается:

VarSetCapacity(r, 1000)   ; максимальное количество символов одной замены*2 (взял с запасом)

msgbox % RegExReplace("1a2b3c4d5", "\d(?C:Match)", r)

Match()
{
   global
   Random, r, 0, 999
   r .= ""
}

20

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

Здесь глобальные переменные в функции используются, нехорошо.

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

21

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

Ну и что - зато скорость увеличивается в разы.

22

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

Ценой возможных багов. А потом я не уверен, что в разы. Вот более чистый вариант:

text =
(
§1
§2
§1
§2
§1
§2
§3
)

p := "sU)(§\d)(.*\R.*\1)", m := ""
While RegExMatch(text, "O" . p, m, m ? m.Pos + m.Len + StrLen(r_num)*2 + 7 : 1)
{
   Random, r_num, 10545530, 99453649
   text := RegExReplace(text, m[0], m[1] . "[[" . r_num . "]]" . m[2] . "@" . r_num . "@",, 1, m.Pos)
}
MsgBox % text

Сравни его и свой.

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

23

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

Я сравнивал так:

setbatchlines -1
loop := 10000
loop % loop
   var .= A_Index

a := a_tickcount
VarSetCapacity(r, 1000)   ; максимальное количество символов одной замены*2 (взял с запасом)
RegExReplace(var, "\d(?C:Match)", r)
msgbox % a_tickcount - a

a := a_tickcount
loop % loop
{
   RegExMatch(var, "\d", match)
   Random, r, 10545530, 99453649
   var := RegExReplace(var, match, r,,1,1)
}
msgbox % a_tickcount - a

Match()
{
   global
   Random, r, 10545530, 99453649
   r .= ""
}

24 (изменено: teadrinker, 2019-08-12 18:41:19)

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

Не очень понял. Зачем VarSetCapacity(r, 1000) ? Там максимум восемь символов. Не уверен, что это корректное сравнение, здесь совсем другое происходит.

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

25

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

VarSetCapacity(r, 1000) - я же написал в скобках, что взял с запасом.
Почему не корректное?
Ты написал, что (в регулярных выражениях) заменять можно только на что-то одно, другие значения для замены вставить никак не получится.
Я привел вариант с коллаут.
А какие могут быть баги через коллаут?
Без глобальных переменных в функциях иногда никак не обойтись - например при асинхронных запросах к серверу.

26

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

Начнём с того, что этот вариант вообще не работает:

MsgBox, % res := RegExReplace("1234", "\d(?C:Match)", r)

Match() {
   global r
   Random, r, 10545530, 99453649
}
Malcev пишет:

Без глобальных переменных в функциях иногда никак не обойтись

У меня таких случаев не было, приведи пример.

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

27

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

Надо r в строку переводить:

Match()
{
   global
   Random, r, 10545530, 99453649
   r .= ""
}
teadrinker пишет:

У меня таких случаев не было, приведи пример.

Последний пример:
https://www.autohotkey.com/docs/command … m#Examples

28

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

Malcev пишет:

Последний пример

#Persistent
req := ComObjCreate("Msxml2.XMLHTTP")
req.open("GET", "https://autohotkey.com/download/1.1/version.txt", true)
req.onreadystatechange := Func("Ready").Bind(req)
req.send()

Ready(req) {
    if (req.readyState != 4)  ; Not done yet.
        return
    if (req.status == 200) ; OK.
        MsgBox % "Latest AutoHotkey version: " req.responseText
    else
        MsgBox 16,, % "Status " req.status
    ExitApp
}
Malcev пишет:

Надо r в строку переводить

А целиком код?

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

29

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

VarSetCapacity(r, 16)
MsgBox, % res := RegExReplace("1234", "\d(?C:Match)", r)

Match() {
   global r
   Random, r, 10545530, 99453649
   r .= ""
}

30

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

text =
(
§1
§2
§1
§2
§1
§2
§3
)

VarSetCapacity(r, 16)
MsgBox, % res := RegExReplace(text, "sU)(§\d)(.*\R.*\1)(?C:Match)", "$1[[" r "]]$2@" r "@")
Match(m) {
   global r
   Random, r, 10545530, 99453649
   r .= ""
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

31

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

Ты такой результат ожидаешь?

text =
(
§1
§2
§1
§2
§1
§2
§3
)

VarSetCapacity(r, 1000)
MsgBox, % res := RegExReplace(text, "sU)(§\d)(.*\R.*\1)(?C:Match)", r)
Match(m) {
   global r
   Random, r, 10545530, 99453649
   r := m1 "[[" r "]]" m2 "@" r "@"
}

32 (изменено: teadrinker, 2019-08-12 19:30:17)

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

Ну типа того. А теперь можно и сравнить:

SetBatchLines, -1
text =
(
§1
§2
§1
§2
§1
§2
§3
)
text1 := text

start := A_TickCount
Loop 100000 {
   m := "", text := text1
   While RegExMatch(text, "sUO)(§\d)(.*\R.*\1)", m, m ? m.Pos + m.Len + StrLen(r_num)*2 + 7 : 1)
   {
      Random, r_num, 10545530, 99453649
      text := RegExReplace(text, m[0], m[1] . "[[" . r_num . "]]" . m[2] . "@" . r_num . "@",, 1, m.Pos)
   }
}
res1 := A_TickCount - start
start := A_TickCount
VarSetCapacity(r, 1000)
Loop 100000
   res := RegExReplace(text1, "sU)(§\d)(.*\R.*\1)(?C:Match)", r)
res2 := A_TickCount - start

MsgBox, % res1 "`n" res2

Match(m) {
   global r
   Random, r, 10545530, 99453649
   r := m1 "[[" r "]]" m2 "@" r "@"
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

33

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

Подправил. Но в моём случае лишнее присваивание для теста делать приходится. Разница есть, но небольшая.

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

34

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

Malcev пишет:

А какие могут быть баги через коллаут?

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

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

35

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

Да, теперь можно и сравнить:

#MaxMem 4095
SetBatchLines, -1
text =
(
§1
§2
§1
§2
§1
§2
§3
)
loop 12
   text .= "`n" text
text1 := text

start := A_TickCount
Loop 1 {
   m := ""
   While RegExMatch(text, "sUO)(§\d)(.*\R.*\1)", m, m ? m.Pos + m.Len + StrLen(r_num)*2 + 7 : 1)
   {
      Random, r_num, 10545530, 99453649
      text := RegExReplace(text, m[0], m[1] . "[[" . r_num . "]]" . m[2] . "@" . r_num . "@",, 1, m.Pos)
   }
}
res1 := A_TickCount - start
start := A_TickCount
VarSetCapacity(r, 1000)
Loop 1
   res := RegExReplace(text1, "sU)(§\d)(.*\R.*\1)(?C:Match)", r)
res2 := A_TickCount - start

MsgBox, % res1 "`n" res2

Match(m) {
   global r
   Random, r, 10545530, 99453649
   r := m1 "[[" r "]]" m2 "@" r "@"
}

36

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

Спасибо! Как изменить, чтобы была сделана только одна замена, после первого совпадения по шаблону?

text =
(
§1
§2
§1
§2
§1
§2
§3
)

p := "sU)(§\d)(.*\R.*\1)", m := ""
While RegExMatch(text, "O" . p, m, m ? m.Pos + m.Len + StrLen(r_num)*2 + 7 : 1)
{
   Random, r_num, 10545530, 99453649
   text := RegExReplace(text, p, "$1[[" r_num "]]$2@" r_num "@",, 1, m.Pos)
}
MsgBox % text

37

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

Понял — break надо добавить).

38

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

Malcev, ну уговорил, с очень большим текстом можно и подумать, какой вариант применить.

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

39

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

А что там с невозможностью избежать глобальных переменных?

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

40

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

#Persistent
loop 5
{
   req%A_Index% := ComObjCreate("Msxml2.XMLHTTP")
   req%A_Index%.open("GET", "https://autohotkey.com/download/1.1/version.txt", true)
   req%A_Index%.onreadystatechange := Func("Ready").Bind(A_Index)
   req%A_Index%.send()
}

Ready(Index)
{
   Global
   if (req%Index%.readyState = 4)
      req%Index% := ""    ;   делаем какие-либо действия связанные с этим объектом, например обнуляем
   return
}

41

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

А что этот пример демонстрирует? Так сразу и не понятно. Если забиндить req%A_Index% вместо A_Index, не будет то же самое без global? И как это увидеть?

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

42 (изменено: Malcev, 2019-08-12 21:01:58)

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

У меня в коде при заливке на filemail файл отправляется частями.
И после отправки определенной части переменную в которой она хранится следует удалять, чтобы не съедалась память, то есть я обнулял HTTP%Index% и body%Index%.
Без Global у меня такое не получалось:
http://forum.script-coding.com/viewtopic.php?id=13727

43

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

teadrinker пишет:

Если забиндить req%A_Index% вместо A_Index, не будет то же самое без global?

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

44

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

Приводишь пример, который проверить проблематично, попроще нет?

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

45

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

Сравни:

#Persistent
loop 1
{
   req%A_Index% := ComObjCreate("Msxml2.XMLHTTP")
   req%A_Index%.open("GET", "https://autohotkey.com/download/1.1/version.txt", true)
   req%A_Index%.onreadystatechange := Func("Ready").Bind(A_Index)
   req%A_Index%.send()
}
sleep 5000
msgbox % IsObject(req1)


Ready(Index)
{
   Global
   if (req%Index%.readyState = 4)
      req%Index% := ""    ;   делаем какие-либо действия связанные с этим объектом, например обнуляем
   return
}
#Persistent
loop 1
{
   req%A_Index% := ComObjCreate("Msxml2.XMLHTTP")
   req%A_Index%.open("GET", "https://autohotkey.com/download/1.1/version.txt", true)
   req%A_Index%.onreadystatechange := Func("Ready").Bind(req%A_Index%)
   req%A_Index%.send()
}
sleep 5000
msgbox % IsObject(req1)

Ready(Index)
{
   if (Index.readyState = 4)
      Index := ""    ;   делаем какие-либо действия связанные с этим объектом, например обнуляем
   return
}

46

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

Так не проще:

#Persistent
loop 5
{
   req%A_Index% := ComObjCreate("Msxml2.XMLHTTP")
   req%A_Index%.open("GET", "https://autohotkey.com/download/1.1/version.txt", true)
   req%A_Index%.onreadystatechange := Func("Ready").Bind(req%A_Index%)
   req%A_Index%.send()
   req%A_Index% := ""
}

Ready(req)
{
   if (req.readyState = 4)
      MsgBox, % req.responseText
}

?

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

47

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

Может, ещё внутри функции обнулить нужно, чтобы память освободить, не уверен.

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

48

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

Так надо еще body%A_Index% обнулять, а его можно обнулить только после окончания отправки данных.

49

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

А в чём проблема? После Send и обнуляй.

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

50 (изменено: Malcev, 2019-08-12 22:50:18)

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

Ты уверен, что так можно делать?
У меня в итоге залился битый mp4 файл.
Сейчас я обнуляю, после того, как получаю ответ от сервера, что эта часть файла загружена, а не сразу после отправки.
Кстати, Lexikos в своих примерах тоже использует Global:
https://github.com/Lexikos/ActiveScript … e_JsRT.ahk

51

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

У меня проблем вроде не возникает, я вообще всё внутри функций делаю, там всё обнуляется автоматически. По идее, метод Send не завершается, пока всё, что в нём указано, не будет отправлено.
Lexikos, думаю, для простоты так делает, чтобы было понятно новичкам.

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

52

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

Для примера:

SendImageToImgur(imagePath, ClientID)  {
   oFile := FileOpen(imagePath, "r")
   oFile.Pos := 0
   oFile.RawRead(buff, size := oFile.length)
   oFile.Close()
   strBase64 := CryptBinaryToStringBASE64(&buff, size, true)
   http := ComObjCreate("Msxml2.XMLHTTP")
   http.open("POST", "https://api.imgur.com/3/image", true)
   http.onreadystatechange := Func("StateChange").Bind(http)
   http.SetRequestHeader("authorization", "Client-ID " . ClientID)
   http.send(strBase64)
   VarSetCapacity(strBase64, 0), VarSetCapacity(buff, 0)
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder