326 (изменено: DD, 2018-07-05 20:52:27)

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

teadrinker, имелся в виду перебор группой. То есть, требуется разом перебирать ту группу ключей, что я выше в примере собрал в msgbox`е, чтобы эти ключи последовательно искались и выводились группой в пределах комментария. В строке, вместе с удалённым — 8 блоков комментариев (граница каждого начинается с ключа "shown":) и надо выводить те из перечисленных ключей, которые присутствуют в каждом из этих блоков.

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

userpic
uname
commenter_journal_base
dtalkid
upictitle
article
ctime
userhead_url
dname

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

327 (изменено: DD, 2018-07-05 20:54:14)

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

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

y_cmts .= "`n<div class=""comment"">`n<img class=""img"" src=""" match3 """>`n<div class=""info""><a href=""" match4 """>" match2 "</a> – " match7 "<span class=""vote"">" match6 "</span></div>`n<div class=""content"">" match5 "</div>`n</div>`n`n"

328 (изменено: teadrinker, 2018-07-05 21:03:27)

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

DD пишет:

Типа этого

Вообще не понимаю, о чём речь. Если нужно перебрать все "блоки", то так:

str =
(
{"replycount":173,"comments":[{"collapsed":0,"shown":1,"collapsed":0,"userpic":"https://l-userpic.livejournal.com/125166311/76306440","actions":[{"allowed":1,"href":"https://livejournal.com/2796915.html?replyto=1321676147","name":"reply","title":"Ответить","footer":1},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321676147#t1321676147","name":"permalink","title":"ссылка"},{"checkbox":1,"allowed":1,"name":"checkbox","title":"Выбрать"},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321676147#t1321676147","name":"collapse","title":"Свернуть"},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321676147#t1321676147","name":"expand","title":"Развернуть"}],"uname":"leyb_bronshteyn","loaded":1,"p_tracked":0,"commenter_journal_base":"https://leyb-bronshteyn.livejournal.com/","statprefix":"https://l-stat.livejournal.net","lj_statprefix":"https://l-stat.livejournal.net","dtalkid":1321676147,"talkid":5162797,"thread_url":"https://livejournal.com/2796915.html?thread=1321676147#t1321676147","above":1321663091,"upictitle":"leyb_bronshteyn: trotsky","article":"КОММЕНТАРИЙ1","controls":[{"checkbox":1,"allowed":1,"name":"checkbox","title":"Выбрать"},{"allowed":1,"href":"https://www.livejournal.com/manage/subscriptions/comments.bml?talkid=1321676147&journal=jour","name":"track","title":"Отслеживать"}],"siteroot":"https://www.livejournal.com","poster":"tema","stime":"4 дня назад","ctime":"30 июня 2018, 17:12:32 UTC","parent":1321663091,"massactions":1,"subject":"","deleted":0,"username":[{"journal_url":"https://leyb-bronshteyn.livejournal.com/","striked":null,"journaltype":"P","userhead_url":"https://l-stat.livejournal.net/img/userinfo_v8.svg?v=17080?v=257.1","color":null,"noctxpopup":0,"side_alias":0,"journal":"leyb_bronshteyn","inline_css":0,"attrs":null,"is_identity":0,"bold":1,"show_userhead":1,"username":"leyb_bronshteyn","user_alias":"","profile_url":"https://leyb-bronshteyn.livejournal.com/profile","alias":0}],"is_promo":0,"dname":"leyb_bronshteyn","ctime_ts":1530378752,"is_best":0,"tracked":0},{"shown":0,"collapsed":1,"uname":"","loaded":0,"p_tracked":0,"commenter_journal_base":"","statprefix":"https://l-stat.livejournal.net","lj_statprefix":"https://l-stat.livejournal.net","dtalkid":1321677683,"talkid":5162803,"thread_url":"https://livejournal.com/2796915.html?thread=1321677683#t1321677683","above":1321676147,"siteroot":"https://www.livejournal.com","poster":"tema","stime":"4 дня назад","below":1321699955,"parent":1321676147,"massactions":1,"deleted":1,"is_promo":0,"dname":"","ctime_ts":1530378800,"leafclass":"deleted","is_best":0,"tracked":0},{"shown":1,"collapsed":0,"userpic":"https://l-userpic.livejournal.com/121339544/65211451","actions":[{"allowed":1,"href":"https://livejournal.com/2796915.html?replyto=1321846131","name":"reply","title":"Ответить","footer":1},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321846131#t1321846131","name":"permalink","title":"ссылка"},{"checkbox":1,"allowed":1,"name":"checkbox","title":"Выбрать"},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321846131#t1321846131","name":"collapse","title":"Свернуть"},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321846131#t1321846131","name":"expand","title":"Развернуть"}],"uname":"ext_2042553","loaded":1,"p_tracked":0,"commenter_journal_base":"http://my.mail.ru/list/iwasko/","statprefix":"https://l-stat.livejournal.net","lj_statprefix":"https://l-stat.livejournal.net","dtalkid":1321846131,"talkid":5163461,"thread_url":"https://livejournal.com/2796915.html?thread=1321846131#t1321846131","above":1321806195,"upictitle":"Иван Пирогов: pic#121339544","article":"КОММЕНТАРИЙ2","controls":[{"checkbox":1,"allowed":1,"name":"checkbox","title":"Выбрать"},{"allowed":1,"href":"https://www.livejournal.com/manage/subscriptions/comments.bml?talkid=1321846131&journal=jour","name":"track","title":"Отслеживать"}],"siteroot":"https://www.livejournal.com","poster":"tema","stime":"3 дня назад","ctime":"1 июля 2018, 16:26:49 UTC","parent":1321806195,"massactions":1,"subject":"","deleted":0,"username":[{"journal_url":"http://my.mail.ru/list/iwasko/","striked":null,"journaltype":"I","userhead_url":"https://l-stat.livejournal.net/img/mailru-profile.gif?v=12149?v=257.1","color":null,"noctxpopup":0,"side_alias":0,"journal":"Иван Пирогов","inline_css":0,"attrs":null,"is_identity":1,"bold":1,"show_userhead":1,"username":"ext_2042553","user_alias":"","profile_url":"https://www.livejournal.com/profile?userid=65211451&t=I","alias":0}],"is_promo":0,"dname":"Иван Пирогов","ctime_ts":1530462409,"is_best":0,"tracked":0},{"shown":1,"collapsed":0,"actions":[{"allowed":1,"href":"https://livejournal.com/2796915.html?replyto=1321712499","name":"reply","title":"Ответить","footer":1},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321712499#t1321712499","name":"permalink","title":"ссылка"},{"checkbox":1,"allowed":1,"name":"checkbox","title":"Выбрать"},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321712499#t1321712499","name":"collapse","title":"Свернуть"},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321712499#t1321712499","name":"expand","title":"Развернуть"}],"uname":"v_unitaz","loaded":1,"p_tracked":0,"commenter_journal_base":"https://v-unitaz.livejournal.com/","statprefix":"https://l-stat.livejournal.net","lj_statprefix":"https://l-stat.livejournal.net","dtalkid":1321712499,"talkid":5162939,"thread_url":"https://livejournal.com/2796915.html?thread=1321712499#t1321712499","above":1321677683,"upictitle":"v_unitaz: pic#0","article":"КОММЕНТАРИЙ3","controls":[{"checkbox":1,"allowed":1,"name":"checkbox","title":"Выбрать"},{"allowed":1,"href":"https://www.livejournal.com/manage/subscriptions/comments.bml?talkid=1321712499&journal=jour","name":"track","title":"Отслеживать"}],"siteroot":"https://www.livejournal.com","poster":"tema","stime":"4 дня назад","ctime":"30 июня 2018, 19:08:18 UTC","parent":1321677683,"massactions":1,"subject":"","deleted":0,"username":[{"journal_url":"https://v-unitaz.livejournal.com/","striked":null,"journaltype":"P","userhead_url":"https://l-stat.livejournal.net/img/userinfo_v8.svg?v=17080?v=257.1","color":null,"noctxpopup":0,"side_alias":0,"journal":"v_unitaz","inline_css":0,"attrs":null,"is_identity":0,"bold":1,"show_userhead":1,"username":"v_unitaz","user_alias":"","profile_url":"https://v-unitaz.livejournal.com/profile","alias":0}],"is_promo":0,"dname":"v_unitaz","ctime_ts":1530385698,"is_best":0,"tracked":0},{"shown":1,"collapsed":0,"userpic":"https://l-userpic.livejournal.com/127834290/83644284","actions":[{"allowed":1,"href":"https://livejournal.com/2796915.html?replyto=1321713779","name":"reply","title":"Ответить","footer":1},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321713779#t1321713779","name":"permalink","title":"ссылка"},{"checkbox":1,"allowed":1,"name":"checkbox","title":"Выбрать"},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321713779#t1321713779","name":"collapse","title":"Свернуть"},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321713779#t1321713779","name":"expand","title":"Развернуть"}],"uname":"lovelement","loaded":1,"p_tracked":0,"commenter_journal_base":"https://lovelement.livejournal.com/","statprefix":"https://l-stat.livejournal.net","lj_statprefix":"https://l-stat.livejournal.net","dtalkid":1321713779,"talkid":5162944,"thread_url":"https://livejournal.com/2796915.html?thread=1321713779#t1321713779","above":1321712499,"upictitle":"lovelement: pic#127834290","article":"КОММЕНТАРИЙ4","controls":[{"checkbox":1,"allowed":1,"name":"checkbox","title":"Выбрать"},{"allowed":1,"href":"https://www.livejournal.com/manage/subscriptions/comments.bml?talkid=1321713779&journal=jour","name":"track","title":"Отслеживать"}],"siteroot":"https://www.livejournal.com","poster":"tema","stime":"4 дня назад","below":1321768563,"ctime":"30 июня 2018, 19:15:49 UTC","parent":1321712499,"massactions":1,"subject":"","deleted":0,"username":[{"journal_url":"https://lovelement.livejournal.com/","striked":null,"journaltype":"P","userhead_url":"https://l-stat.livejournal.net/img/userinfo_v8.svg?v=17080?v=257.1","color":null,"noctxpopup":0,"side_alias":0,"journal":"lovelement","inline_css":0,"attrs":null,"is_identity":0,"bold":1,"show_userhead":1,"username":"lovelement","user_alias":"","profile_url":"https://lovelement.livejournal.com/profile","alias":0}],"is_promo":0,"dname":"lovelement","ctime_ts":1530386149,"is_best":0,"tracked":0},{"shown":1,"collapsed":0,"actions":[{"allowed":1,"href":"https://livejournal.com/2796915.html?replyto=1321720435","name":"reply","title":"Ответить","footer":1},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321720435#t1321720435","name":"permalink","title":"ссылка"},{"checkbox":1,"allowed":1,"name":"checkbox","title":"Выбрать"},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321720435#t1321720435","name":"collapse","title":"Свернуть"},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321720435#t1321720435","name":"expand","title":"Развернуть"}],"uname":"v_unitaz","loaded":1,"p_tracked":0,"commenter_journal_base":"https://v-unitaz.livejournal.com/","statprefix":"https://l-stat.livejournal.net","lj_statprefix":"https://l-stat.livejournal.net","dtalkid":1321720435,"talkid":5162970,"thread_url":"https://livejournal.com/2796915.html?thread=1321720435#t1321720435","above":1321713779,"upictitle":"v_unitaz: pic#0","article":"КОММЕНТАРИЙ5","controls":[{"checkbox":1,"allowed":1,"name":"checkbox","title":"Выбрать"},{"allowed":1,"href":"https://www.livejournal.com/manage/subscriptions/comments.bml?talkid=1321720435&journal=jour","name":"track","title":"Отслеживать"}],"siteroot":"https://www.livejournal.com","poster":"tema","stime":"4 дня назад","ctime":"30 июня 2018, 20:29:16 UTC","parent":1321713779,"massactions":1,"subject":"","deleted":0,"username":[{"journal_url":"https://v-unitaz.livejournal.com/","striked":null,"journaltype":"P","userhead_url":"https://l-stat.livejournal.net/img/userinfo_v8.svg?v=17080?v=257.1","color":null,"noctxpopup":0,"side_alias":0,"journal":"v_unitaz","inline_css":0,"attrs":null,"is_identity":0,"bold":1,"show_userhead":1,"username":"v_unitaz","user_alias":"","profile_url":"https://v-unitaz.livejournal.com/profile","alias":0}],"is_promo":0,"dname":"v_unitaz","ctime_ts":1530390556,"is_best":0,"tracked":0},{"shown":1,"collapsed":0,"userpic":"https://l-userpic.livejournal.com/127834290/83644284","actions":[{"allowed":1,"href":"https://livejournal.com/2796915.html?replyto=1321720691","name":"reply","title":"Ответить","footer":1},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321720691#t1321720691","name":"permalink","title":"ссылка"},{"checkbox":1,"allowed":1,"name":"checkbox","title":"Выбрать"},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321720691#t1321720691","name":"collapse","title":"Свернуть"},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321720691#t1321720691","name":"expand","title":"Развернуть"}],"uname":"lovelement","loaded":1,"p_tracked":0,"commenter_journal_base":"https://lovelement.livejournal.com/","statprefix":"https://l-stat.livejournal.net","lj_statprefix":"https://l-stat.livejournal.net","dtalkid":1321720691,"talkid":5162971,"thread_url":"https://livejournal.com/2796915.html?thread=1321720691#t1321720691","above":1321720435,"upictitle":"lovelement: pic#127834290","article":"КОММЕНТАРИЙ6","controls":[{"checkbox":1,"allowed":1,"name":"checkbox","title":"Выбрать"},{"allowed":1,"href":"https://www.livejournal.com/manage/subscriptions/comments.bml?talkid=1321720691&journal=jour","name":"track","title":"Отслеживать"}],"siteroot":"https://www.livejournal.com","poster":"tema","stime":"4 дня назад","ctime":"30 июня 2018, 20:35:06 UTC","parent":1321720435,"massactions":1,"subject":"","deleted":0,"username":[{"journal_url":"https://lovelement.livejournal.com/","striked":null,"journaltype":"P","userhead_url":"https://l-stat.livejournal.net/img/userinfo_v8.svg?v=17080?v=257.1","color":null,"noctxpopup":0,"side_alias":0,"journal":"lovelement","inline_css":0,"attrs":null,"is_identity":0,"bold":1,"show_userhead":1,"username":"lovelement","user_alias":"","profile_url":"https://lovelement.livejournal.com/profile","alias":0}],"is_promo":0,"dname":"lovelement","ctime_ts":1530390906,"is_best":0,"tracked":0},{"shown":1,"collapsed":0,"userpic":"https://l-userpic.livejournal.com/82196355/5817510","actions":[{"allowed":1,"href":"https://livejournal.com/2796915.html?replyto=1321717619","name":"reply","title":"Ответить","footer":1},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321717619#t1321717619","name":"permalink","title":"ссылка"},{"checkbox":1,"allowed":1,"name":"checkbox","title":"Выбрать"},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321717619#t1321717619","name":"collapse","title":"Свернуть"},{"allowed":1,"href":"https://livejournal.com/2796915.html?thread=1321717619#t1321717619","name":"expand","title":"Развернуть"}],"uname":"poulsam","loaded":1,"p_tracked":0,"commenter_journal_base":"https://poulsam.livejournal.com/","statprefix":"https://l-stat.livejournal.net","lj_statprefix":"https://l-stat.livejournal.net","dtalkid":1321717619,"talkid":5162959,"thread_url":"https://livejournal.com/2796915.html?thread=1321717619#t1321717619","above":1321695859,"upictitle":"Poul: pic#82196355","article":"КОММЕНТАРИЙ7","controls":[{"checkbox":1,"allowed":1,"name":"checkbox","title":"Выбрать"},{"allowed":1,"href":"https://www.livejournal.com/manage/subscriptions/comments.bml?talkid=1321717619&journal=jour","name":"track","title":"Отслеживать"}],"siteroot":"https://www.livejournal.com","poster":"tema","stime":"4 дня назад","ctime":"30 июня 2018, 19:47:49 UTC","parent":1321650291,"massactions":1,"subject":"","deleted":0,"username":[{"journal_url":"https://poulsam.livejournal.com/","striked":null,"journaltype":"P","userhead_url":"https://l-stat.livejournal.net/img/userinfo_v8.svg?v=17080?v=257.1","color":null,"noctxpopup":0,"side_alias":0,"journal":"poulsam","inline_css":0,"attrs":null,"is_identity":0,"bold":1,"show_userhead":1,"username":"poulsam","user_alias":"","profile_url":"https://poulsam.livejournal.com/profile","alias":0}],"is_promo":0,"dname":"poulsam","ctime_ts":1530388069,"is_best":0,"tracked":0}]}
)

obj := JSON.Parse(str)
keys =
(
userpic
uname
commenter_journal_base
dtalkid
upictitle
article
ctime
userhead_url
dname
)

for k, v in obj.comments  {
   Loop, parse, keys, `n, `r
      %A_LoopField%%k% := SearchKey(v, A_LoopField)
}

MsgBox, % userpic1 . "`n" . userpic2 . "`n" . userpic3
MsgBox, % uname1 . "`n" . uname2 . "`n" . uname3

SearchKey(obj, key)  {
   for k, v in obj  {
      if (k = key)
         Return v
      
      if IsObject(v)  {
         res := SearchKey(v, key)
         if (res != "")
            Return res
      }
   }
}

class JSON
{
   static JS := JSON._GetJScripObject()
   
   Parse(JsonString)  {
      try oJSON := this.JS.("(" JsonString ")")
      catch  {
         MsgBox, Wrong JsonString!
         Return
      }
      Return this._CreateObject(oJSON)
   }

   _GetJScripObject()  {
      VarSetCapacity(tmpFile, (MAX_PATH := 260) << !!A_IsUnicode, 0)
      DllCall("GetTempFileName", Str, A_Temp, Str, "AHK", UInt, 0, Str, tmpFile)
      
      FileAppend,
      (
      <component>
      <public><method name='eval'/></public>
      <script language='JScript'></script>
      </component>
      ), % tmpFile
      
      JS := ObjBindMethod( ComObjGet("script:" . tmpFile), "eval" )
      FileDelete, % tmpFile
      JSON._AddMethods(JS)
      Return JS
   }

   _AddMethods(ByRef JS)  {
      JScript =
      (
         Object.prototype.GetKeys = function () {
            var keys = []
            for (var k in this)
               if (this.hasOwnProperty(k))
                  keys.push(k)
            return keys
         }
         Object.prototype.IsArray = function () {
            var toStandardString = {}.toString
            return toStandardString.call(this) == '[object Array]'
         }
      )
      JS.("delete ActiveXObject; delete GetObject;")
      JS.(JScript)
   }

   _CreateObject(ObjJS)  {
      res := ObjJS.IsArray()
      if (res = "")
         Return ObjJS
      
      else if (res = -1)  {
         obj := []
         Loop % ObjJS.length
            obj[A_Index] := this._CreateObject(ObjJS[A_Index - 1])
      }
      else if (res = 0)  {
         obj := {}
         keys := ObjJS.GetKeys()
         Loop % keys.length
            k := keys[A_Index - 1], obj[k] := this._CreateObject(ObjJS[k])
      }
      Return obj
   }
}

Значение userpic в первом блоке будет сохранено в переменную userpic1, во втором — userpic2 и т. д. Дальше сами думайте.

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

329 (изменено: DD, 2018-07-05 21:48:27)

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

Почти то, что надо, спасибо! Оказалось, что всё уже настроено на работу в пределах блоков. Но остались вопросы: почему надо добавлять эти порядковые номера после переменных и почему автоматически не происходит перебор всех последующих блоков? Для этого можно вроде использовать loop, подставляя к переменной порядковый номер цикла, —


loop
   MsgBox, % userpic%a_index% "`n" uname%a_index% "`n" commenter_journal_base%a_index% "`n" dtalkid%a_index% "`n" upictitle%a_index% "`n" article%a_index% "`n" ctime%a_index% "`n" userhead_url%a_index% "`n" dname%a_index% "`n"

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


mrg .= "<b>" userpic "</b>`n" ;...

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

330

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

DD пишет:

почему надо добавлять эти порядковые номера после переменных и почему автоматически не происходит перебор всех последующих блоков?

Перебор блоков и создание переменных происходят в этом цикле:

for k, v in obj.comments  {
   Loop, parse, keys, `n, `r
      %A_LoopField%%k% := SearchKey(v, A_LoopField)
}

Количество блоков равно obj.comments.MaxIndex().

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

331

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

teadrinker, пользуюсь вашим json-парсером. Есть недостаток:
Строка(представляет из себя json-массив) конвертируется в объект без проблем, а вот обратно идет округление до N-нулей после запятой.
Как можно отключить округление?

Наглядный пример:


obj:=JSON.Parse("[2.460]")
MsgBox, % JSON.Stringify(obj[1])

332 (изменено: teadrinker, 2018-07-11 17:54:43)

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

Парсер тут ни при чём, просто при любых действиях с числами с запятой они в AHK по умолчанию округляются до шестого знака после запятой:

var := 0.1
MsgBox, % var + 0

Это можно изменить с помощью команды Format.
Если представить число, как строку, тогда увеличения количества цифр после запятой не произойдёт:

obj:=JSON.Parse("[""2.460""]")
MsgBox, % JSON.Stringify(obj[1])

class JSON
{
   static JS := JSON._GetJScripObject()
   
   Parse(JsonString)  {
      try oJSON := this.JS.("(" JsonString ")")
      catch  {
         MsgBox, Wrong JsonString!
         Return
      }
      Return this._CreateObject(oJSON)
   }
   
   Stringify(obj)  {
      if IsObject( obj )  {
         isArray := true
         for key in obj
            if !( key = A_Index || isArray := false )
               break
            
         for k, v in obj
            str .= ( A_Index = 1 ? "" : "," ) . ( isArray ? "" : this.Stringify(k) . ":" ) . this.Stringify(v)

         return isArray ? "[" str "]" : "{" str "}"
      }
      else if (obj*1)
         return obj
      
      for k, v in [["\", "\\"], [A_Tab, "\t"], ["""", "\"""], ["/", "\/"], ["`n", "\n"], ["`r", "\r"], [Chr(12), "\f"], [Chr(08), "\b"]]
         obj := StrReplace( obj, v[1], v[2] )
      
      while RegexMatch( obj, "[^\x20-\x7e]", key )  {
         str := Asc( key )
         val := "\u" . Chr( ( ( str >> 12 ) & 15 ) + ( ( ( str >> 12 ) & 15 ) < 10 ? 48 : 55 ) )
               . Chr( ( ( str >> 8 ) & 15 ) + ( ( ( str >> 8 ) & 15 ) < 10 ? 48 : 55 ) )
               . Chr( ( ( str >> 4 ) & 15 ) + ( ( ( str >> 4 ) & 15 ) < 10 ? 48 : 55 ) )
               . Chr( ( str & 15 ) + ( ( str & 15 ) < 10 ? 48 : 55 ) )
         obj := StrReplace(obj, key, val)
      }
      Return """" obj """"
   }
   
   GetFromUrl(url, body := "", contentType := "", userAgent := "")  {
      ; в случае удачи будет возвращена строка, в случае ошибки — массив с одним элементом-строкой с описанием ошибки
      try  {
         XmlHttp := ComObjCreate("Microsoft.XmlHttp")
         XmlHttp.Open("GET", url, false)
         ( contentType && XmlHttp.SetRequestHeader("Content-Type", contentType) )
         ( userAgent && XmlHttp.SetRequestHeader("User-Agent", userAgent) )
         XmlHttp.Send(body)
      }
      catch e
         Return ["Error!`n" . e.Message]
      status := XmlHttp.Status
      Return status = 200 ? XmlHttp.ResponseText : ["Error! Status: " . status . ", ResponseText: " . XmlHttp.ResponseText]
   }

   _GetJScripObject()  {
      VarSetCapacity(tmpFile, ((MAX_PATH := 260) - 14) << !!A_IsUnicode, 0)
      DllCall("GetTempFileName", Str, A_Temp, Str, "AHK", UInt, 0, Str, tmpFile)
      
      FileAppend,
      (
      <component>
      <public><method name='eval'/></public>
      <script language='JScript'></script>
      </component>
      ), % tmpFile
      
      JS := ObjBindMethod( ComObjGet("script:" . tmpFile), "eval" )
      FileDelete, % tmpFile
      JSON._AddMethods(JS)
      Return JS
   }

   _AddMethods(ByRef JS)  {
      JScript =
      (
         Object.prototype.GetKeys = function () {
            var keys = []
            for (var k in this)
               if (this.hasOwnProperty(k))
                  keys.push(k)
            return keys
         }
         Object.prototype.IsArray = function () {
            var toStandardString = {}.toString
            return toStandardString.call(this) == '[object Array]'
         }
      )
      JS.("delete ActiveXObject; delete GetObject;")
      JS.(JScript)
   }

   _CreateObject(ObjJS)  {
      res := ObjJS.IsArray()
      if (res = "")
         Return ObjJS
      
      else if (res = -1)  {
         obj := []
         Loop % ObjJS.length
            obj[A_Index] := this._CreateObject(ObjJS[A_Index - 1])
      }
      else if (res = 0)  {
         obj := {}
         keys := ObjJS.GetKeys()
         Loop % keys.length
            k := keys[A_Index - 1], obj[k] := this._CreateObject(ObjJS[k])
      }
      Return obj
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

333

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

DD пишет:

Регулярно выражаясь, как задать в исключаемом перечне (в этом: [^символы]) совпадение не по одному, а  целиком по двум, трём символам (тег, например)?

Использовал ((?!НЕЭТО).)*, но выяснилось, что шаблон иногда отказывает. Имеется ли надежный аналог для AHK-скриптов?

334

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

Была инфа, что эффективней записывать этот шаблон следующим образом: (?:(?!НЕЭТО).)*, но так на AHK не работает.

335

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

DD, выражайтесь конкретнее, с примерами. В AHK встроен стандартный PCRE.

336 (изменено: DD, 2018-10-24 20:44:33)

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

Следующее выражение означает один любой символ из тех, которых нет в перечне: [^НЕЭТО]*. При использовании, перебор остановится на любой из перечисленных букв.
А нужен вариант выражения для исключения сразу по группе символов, а не по одному, как выше. То есть, вариант для выражений ((?!НЕЭТО).)* и (?:(?!НЕЭТО).)*, которые не подходят.

337

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

Используйте отрицательную вперед смотрящую группу.

338

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

stealzy, а если конкретнее, с примерами?))

339 (изменено: stealzy, 2018-10-24 23:02:41)

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

Вашего примера так и не увидел, ну ладно, вот вам мой:

MsgBox % RegexMatch("точтото", "то(?!НЕЭТО)")
MsgBox % RegexMatch("тоНЕЭТО", "то(?!НЕЭТО)")

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

340

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

Так понял, нужно что-то вроде этого:

str := "1ab2cd3ef"
RegExMatch(str, "\d(?!ab|cd)", match)
MsgBox, % match

Пример получает из строки цифру, после которой нет ab или cd.

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

341 (изменено: DD, 2018-10-25 00:50:36)

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

stealzy, про вперед смотрящие я знаю и иногда использую. Интересовало, как этот принцип применить к исключению по группе символов — как если бы это был один символ, в отличие от символа из перечня. Суть изложенного еще до награмождений была в указании разницы между известным шаблоном для поиска по одному символу ([^x]), и двумя вариантами шаблона с тем же принципом для поиска по группе символов (((?!НЕЭТО).)* || (?:(?!НЕЭТО).)*), с просьбой подсказать третий вариант. К примеру, ниже надо найти то, что для наглядности выделено капслоком:

str := 
(
</div></div></div></div></div></div><div></div><DIV ID="COMPOSER-123456789"><FORM><INPUT /><INPUT /><LABEL>_</LABEL><TABLE><TBODY><TR><TD><DIV><TABLE><TBODY><TR><TD><TEXTAREA ID="COMPOSERINPUT"></TEXTAREA></TD></TR></TBODY></TABLE></DIV></TD><TD><DIV><INPUT /></DIV></TD></TR></TBODY></TABLE></FORM><FORM><INPUT /><INPUT /><SPAN><INPUT /><SPAN></SPAN><INPUT /></SPAN></FORM></DIV></DIV></DIV></DIV><DIV><DIV><DIV><IMG /><DIV><DIV><A>_</A><A>_</A><A>_</A></DIV></DIV></DIV></DIV></DIV></DIV></DIV><DIV><DIV><A>_</A></DIV></DIV></div></div></body></html>
)
str := RegExReplace(str, "s)((<div[^>]*>)+)?<div[^>]* id=""composer[^""]*""><form((?!<abbr>).)*</a></div></div>", "")
MsgBox, % str

Почему-то на этом примере сама по себе неэффективная конструкция ((?!НЕЭТО).)*, не сработает (в отличие, скажем, от Notepad++). Как здесь применимы вперед смотрящие?

teadrinker, вроде, (?!<abbr>)* тоже не отработает при поиске ОТ и ДО, исключая указанный тег.

342

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

DD, конструкция (?!<abbr>)* не имеет смысла. Что она у вас означает?

DD пишет:

ниже надо найти то, что для наглядности выделено капслоком

Не понятно, по какому принципу вы хотите искать этот текст. Чего именно после него не должно быть? Объясните на словах.

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

343 (изменено: DD, 2018-10-25 01:26:31)

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

teadrinker, задача найти от <DIV ID="COMPOSER — до </A></DIV></DIV>, с условием, чтобы между ними не было тега <abbr>.

344 (изменено: teadrinker, 2018-10-25 03:05:59)

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

str =
(
</div><DIV ID="COMPOSER-123456789">этот текст<abbr>не должен быть найден</A></DIV></DIV></div></div><DIV ID="COMPOSER-123456789">этот текст нужно найти</A></DIV></DIV></a></div></div></div><abbr></a></div></div>
)
RegExMatch(str, "is)<DIV ID=""COMPOSER((?!<abbr>).)*?</a></div></div>", match)
MsgBox, % match
str = 
(
</div></div></div></div></div></div><div></div><DIV ID="COMPOSER-123456789"><FORM><INPUT /><INPUT /><LABEL>_</LABEL><TABLE><TBODY><TR><TD><DIV><TABLE><TBODY><TR><TD><TEXTAREA ID="COMPOSERINPUT"></TEXTAREA></TD></TR></TBODY></TABLE></DIV></TD><TD><DIV><INPUT /></DIV></TD></TR></TBODY></TABLE></FORM><FORM><INPUT /><INPUT /><SPAN><INPUT /><SPAN></SPAN><INPUT /></SPAN></FORM></DIV></DIV></DIV></DIV><DIV><DIV><DIV><IMG /><DIV><DIV><A>_</A><A>_</A><A>_</A></DIV></DIV></DIV></DIV></DIV></DIV></DIV><DIV><DIV><A>_</A></DIV></DIV></div></div></body></html>
)
RegExMatch(str, "is)<DIV ID=""COMPOSER((?!<abbr>).)*?</a></div></div>", match)
MsgBox, % match
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg
+ DD

345 (изменено: DD, 2018-10-25 12:12:44)

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

teadrinker, спасибо! Получается, дело было в неуказанной опции «is)», но с которой заработал в т.ч. валидный вариант поиска с исключением «(?:(?!<abbr>).)*».
Объяснения по сочетанию «is)» не нашёл — что оно означает? Разве отдельный модификатор «s)» не игнорирует регистр символов?

346

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

Странно, как вы это могли не заметить:
http://www.script-coding.com/AutoHotkey/RegExMatch.html

347

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

По переводным статьям всё же лучше не изучать, там далеко не всё.

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

348

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

Начать изучать имхо проще по переводной статье.
А после ее понимания уже почитать на английском.

349

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

Я делаю ровно наоборот. Читаю статьи по программированию всегда на английском, и только если что-то совсем непонятно, ищу аналоги на русском.

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

350 (изменено: DD, 2018-10-25 14:05:48)

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

Malcev, о значении модификаторов по отдельности имел представление — непонятно, как они работают в объединенном виде.

А вот так с "вперед/назад смотрящими" получилось:

str = 
(
</div></div></div></div></div></div><div></div><DIV ID="COMPOSER-123456789"><FORM><INPUT /><INPUT /><LABEL>_</LABEL><TABLE><TBODY><TR><TD><DIV><TABLE><TBODY><TR><TD><TEXTAREA ID="COMPOSERINPUT"></TEXTAREA></TD></TR></TBODY></TABLE></DIV></TD><TD><DIV><INPUT /></DIV></TD></TR></TBODY></TABLE></A></DIV></DIV>sss</FORM><FORM><INPUT /><INPUT /><SPAN><INPUT /><SPAN></SPAN><INPUT /></SPAN></FORM></DIV></DIV></DIV></DIV><DIV><DIV><DIV><IMG /><DIV><DIV><A>_</A><A>_</A><A>_</A></DIV></DIV></DIV></DIV></DIV></DIV></DIV><DIV><DIV><A>_</A></DIV></DIV></div></div></body></html>
)
RegExMatch(str, "is)<DIV ID=""composer[^>]*><form(?!abbr>)((.(?!abbr>)).*)(?=.*</a></div></div>)", match)
MsgBox, % match