; $regexm(<string>, <regex> [, N])[.pos]
; Get the Nth value of match[0] (defaults to N = 1)
; Return its position with .pos
alias regexm {
; parse the full regex as mIRC does
noop $regex(full, $2, /^(?|m(.)?|(/)|^)(.*?)(?:\1(?!.*\1)(.*)$)?$/usD)
; isolate PCRE options from the start of the expression
noop $regex(pcre, $regmlex(full, 1, 2), /^((?:(?!\((?:(?:MARK|PRUNE|SKIP|THEN|\*(?=:))(?::[^()]*)?|ACCEPT|COMMIT)\))\(\*.*?\))*)(.*)/us)
; validate expression
if (!$regex( , $+(/, $regmlex(pcre, 1, 1), |, $regmlex(pcre, 1, 2), /))) {
echo -eagc i * $!regexm: Invalid expression ( $+ $regerrstr $+ )
return
}
var %char, %exp
; find suitable placeholder char
while ($chr($r(2048, 55295)) isin $1) /
%char = $v1
; add \K onto end of given expression
; first wrap entire expression in (?: ), adding \E in case of unterminated \Q
%exp = $+(m, $regmlex(full, 1, 1), $regmlex(pcre, 1, 1), (?: $+ $regmlex(pcre, 1, 2) $+ \E)(?(R)|\K), $regmlex(full, 1, 1), $regmlex(full, 1, 3))
; construct a second expression by transforming the result of subbing the placeholder char where the matches occurred
; run this against the result of subbing the placeholder into the matches of the \K-modified expression above
; and hey presto, you can find the matches with no ambiguity
noop $regex(final, $regsubex($1, %exp, %char), $+(/\Q, $replace($regsubex($1, $2, %char), \E, \E\\E\Q, %char, \E(.*?)\Q $+ %char), \E/u))
; if it's a position we seek, we need to subtract all placeholders factored into the result
if ($prop == pos) return $calc(1 + $regml(final, $3 1).pos - $3 1)
returnex $regml(final, $3 1)
}