<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; AHK: Продвинутый RegExReplace]]></title>
	<link rel="self" href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=11171&amp;type=atom" />
	<updated>2015-12-24T07:20:06Z</updated>
	<generator>PunBB</generator>
	<id>http://forum.script-coding.com/viewtopic.php?id=11171</id>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Продвинутый RegExReplace]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=99897#p99897" />
			<content type="html"><![CDATA[<p><strong>teadrinker</strong>, я это чувствовал, поэтому и выложил сюда ;-). Спасибо, что не подвели.<br />Со временем первый раз вожусь, поэтому так неказисто вышло.</p><p>Постарался оформить как библиотеку:<br /></p><div class="codebox"><pre><code>
; regExReplFunc(haystack, NeedleRegEx, func, p)
; Замена в переменной &lt;haystack&gt; выражений, совпавших с шаблоном &lt;NeedleRegEx&gt; на результат, возвращенный функцией &lt;func&gt;, где
; func - имя ф-ии, p - массив, содержащий параметры для ф-ии.
; Чтобы передать в ф-ию &lt;func&gt; найденное совпадение и его позицию, используются зарезервированные параметры &quot;_value&quot; и &quot;_pos&quot;.
; Если ф-ия &lt;func&gt; возвращает false, замена не производится.

; Пример использования - сдвиг времени в содержимом переменной text только в первых 25 символах содержимого, используя функцию timeShift.
; text =&quot;12:03 - day, 19:27 - evening, 01:34 - night, 16:35&quot;
; MsgBox % &quot;haystack := &quot; text &quot;`n`nregExReplFunc(haystack, &quot;&quot;\d\d:\d\d&quot;&quot;, &quot;&quot;timeShift&quot;&quot;, [&quot;&quot;_value&quot;&quot;, &quot;&quot;_pos&quot;&quot;, 5, 25])&quot; &quot;`n`nResult   := &quot; regExReplFunc(text, &quot;\d\d:\d\d&quot;, &quot;timeShift&quot;, [&quot;_value&quot;, &quot;_pos&quot;, timeShift:=5, dontReplaceAfterSymbols:=25])
; Return
; timeShift(time, pos, shift, dontReplaceAfterSymbols) {
; 	ts := &quot;19900102&quot; . StrReplace(time, &quot;:&quot;)
; 	ts += shift, Hours
; 	FormatTime, newTime, % ts, HH:mm
; 	if (pos &gt; dontReplaceAfterSymbols)
; 		newTime:=false ; не заменять
; 	Return newTime
; }

regExReplFunc(haystack, NeedleRegEx, func, p) {
	; NeedleRegEx options change
		options:=&quot;^[imsxADJUXS]+\)&quot;, denyOptions:=&quot;^[imsxADJUXS]*P(?:[imsxADJUXS]*)\)&quot;
		; Remove &quot;P&quot; from options
		if RegExMatch(NeedleRegEx,denyOptions,do)
			NeedleRegEx := RegExReplace(NeedleRegEx, denyOptions, RegExReplace(do,&quot;P&quot;))
		; Add &quot;O&quot; and &quot;m&quot; to options
		if RegExMatch(NeedleRegEx,options,o) {
			NeedleRegEx := RegExReplace(NeedleRegEx,options,(!InStr(o,&quot;m&quot;) ? &quot;m$0&quot; : &quot;$0&quot;))
			NeedleRegEx := RegExReplace(NeedleRegEx,options,(!InStr(o,&quot;O&quot;) ? &quot;O$0&quot; : &quot;$0&quot;))
		} else NeedleRegEx := &quot;Om)&quot; . NeedleRegEx
	
	pos:=1
	while regexmatch(haystack, NeedleRegEx, Match, pos)
	{
		; replace reserved words &quot;_value&quot;, &quot;_pos&quot; in function parameters array to Match.0 and Match.Pos(0) content.
		pn:={}
		Loop % p.MaxIndex()
			pn[A_Index] := ((p[A_Index] = &quot;_value&quot;) || (p[A_Index] = &quot;_pos&quot;) ) ? p[A_Index](Match) : p[A_Index]
		; don&#039;t replace if function return false
		haystack :=	((replacement:=%func%(pn*)) != false) ? regexreplace(haystack, Match.0, replacement, byRefNumberOfRepl, limit:=1, pos) : haystack
		pos := Match.Pos(0) + Match.Len(0)
	}
	Return haystack
}
_value(Match) {
	Return % Match.0
}
_pos(Match) {
	Return % Match.Pos(0)
}
</code></pre></div>]]></content>
			<author>
				<name><![CDATA[stealzy]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=31937</uri>
			</author>
			<updated>2015-12-24T07:20:06Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=99897#p99897</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: AHK: Продвинутый RegExReplace]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=99895#p99895" />
			<content type="html"><![CDATA[<p><strong>stealzy</strong>, работает! Только перемудрили немного, RegExReplace слишком уж продвинутый у вас получился. <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /><br /></p><div class="codebox"><pre><code>text =
(
627
00:54:37,670 --&gt; 00:54:39,300
- Идем со мною, Мойше.

628
00:54:48,770 --&gt; 00:54:51,100
Делай всё, что скажет
этот хороший дядя.
)

MsgBox, % newText := TimeChange(text, -62)

TimeChange(text, shift)
{
	pos := 0
	while pos := RegExMatch(text, &quot;\d\d:\d\d:\d\d&quot;, match, pos + 1)
		text := RegExReplace(text, match, ShiftTime(match, shift), &quot;&quot;, 1, pos)
	Return text
}

ShiftTime(time, shift)
{
	ts := &quot;16010102&quot; . StrReplace(time, &quot;:&quot;)
	ts += shift, Seconds
	FormatTime, newTime, % ts, HH:mm:ss
	Return newTime
}</code></pre></div>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2015-12-24T00:45:46Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=99895#p99895</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[AHK: Продвинутый RegExReplace]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=99881#p99881" />
			<content type="html"><![CDATA[<p>Возникла тут задача синхронизировать по времени файл субтитров с видео.<br />Файл субтитров .srt оказался текстовым и содержал временные метки в формате hh:mm:ss и привязанные к ним реплики.<br />Для синхронизации нужно сдвинуть все метки на х минут у секунд.</p><p>В качестве побочного эффекта получилась функция, для массовой замены подходящих под RegExp выражений, на результат обработки этих выражений произвольной функцией.<br /></p><div class="codebox"><pre><code>filePath := &quot;S:\kino\The Intern (2015).srt&quot;
shift:=-62 ; sec

FileRead text, %filePath%
modText := RegExReplFunc(text, &quot;\d\d:\d\d:\d\d&quot;, &quot;timeShift&quot;, [shift])
FileMove %filePath%, %filePath%_orig
FileAppend %modText%, %filePath%
Return

RegExReplFunc(haystack, NeedleRegEx, f, p) {
	pos:=1
	NeedleRegEx:= &quot;O)&quot; NeedleRegEx

	while RegExMatch(haystack, NeedleRegEx, Match, pos) {
		matchWord:=Match.Value(0)
		postWord := %f%(matchWord, p*)
		if (postWord != false)
			haystack :=	RegExReplace(haystack, matchWord, postWord, byRefNumberOfRepl, limit:=1, pos)
		pos := Match.Pos(0) + Match.Len(0)
	}

	Return haystack
}

timeShift(time, shift) {
	; 23:30:55 + 100 = 23:32:35
	RegExMatch(time, &quot;O)^\d\d&quot;, Match)
	hh := Match.Value(0)
	RegExMatch(time, &quot;O)(?&lt;=:)\d\d(?=:)&quot;, Match)
	mm := Match.Value(0)
	RegExMatch(time, &quot;O)\d\d$&quot;, Match)
	ss := Match.Value(0)

	t = 19990101 ; дата от балды
	t += hh*3600 + mm*60 + ss, Seconds
	t += %shift%, Seconds
	FormatTime t, %t%, HH:mm:ss

	return t
}
</code></pre></div><p>Offtop: Конечно, должны существовать специально заточенные под работу с сабами программы, но было интересно решение в общем случае.</p>]]></content>
			<author>
				<name><![CDATA[stealzy]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=31937</uri>
			</author>
			<updated>2015-12-23T02:36:07Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=99881#p99881</id>
		</entry>
</feed>
