mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Sep 2003
Posts: 4,230
D
DaveC Offline OP
Hoopy frood
OP Offline
Hoopy frood
D
Joined: Sep 2003
Posts: 4,230
I got a problem Isolating a substring in a string, the problem is some times the string has color bold underline reverse etc (BURK codes) in it.

Im currently using $strip($1-) and locating the string i want, thats easy enough, the hard part is i want to isolate it in the colored version of the string. Once isolated im going to replace it with something else, I dont care if the colors or highlighting is a bit screw when i replace it, just that i can within the colored version.



an example follows of what i want...
in the example i want to replace words 4,5,6 with !!!this-chunk-missing!!!

var %string = t03his text is l04ots of colors a09,07nd other burk c0odes
var %substring = $gettok($strip(%string),4-6,32)
;
; what goes in here to get to below!
;
t03his text is !!!this-chunk-missing!!! a09,07nd other burk c0odes



I was hoping someone would have a brain spinup and think of or know of something to do it easlly, maybe some secret command i dont know or a clever regex maybe?


Currently im searching the %string by taking one char of the right striping it and seeing if it matches the stripped text before my sub string "this text is ", once i match that, i have the front of it, then i move from there forward again charcter by character untill a stripped copy makes matches my %substring thus i have the start and end of it and can replace it.
This is a little task intensive. as its on a ON:TEXT event, currently taking around 125 ticks per line, i could tweak it a little here and there, but was rather hoping someone had a better method?????

PS: above is only an example the true %substring is not always going to be boarderd by spaces, so theres no common stepping stone i can uses to reach it.

Joined: Dec 2002
Posts: 208
C
Fjord artisan
Offline
Fjord artisan
C
Joined: Dec 2002
Posts: 208
The following will do very close to your example

Code:
var %str = t03his text is l04ots of colors a09,07nd other burk c0odes
echo -a * $instok($deltok(%str,4-6,32),!!!this-chunk-missing!!!,4,32)


simply remove the tokens u wish to replace and then insert the new chunk at that pososion .. i was hopeing to simply just use $puttok() but aparently $puttok doesnt alow you to overwrite multipal tokens /me makes a note to request that later

only difference is that it doesnt retain the CTRL+R chr before the chunk as u have in your example .. ibeings the CTRL+R is part of the 4-6 tokens i dont know why u would retain it.

if u can explain what kind of rule u want to use for retaining it (perhaps keep all ctrlcodes that exist before but are still atatched to the first token to be removed) or something like that we can figure something out.

hope this helps.

Cobra^

Joined: Sep 2003
Posts: 4,230
D
DaveC Offline OP
Hoopy frood
OP Offline
Hoopy frood
D
Joined: Sep 2003
Posts: 4,230
You missed the PS note at the bottom, there is no token identifiers to isolate the substring on, if there were i would have simply removed the substring as per your example.

It maybe as follows also


var %string = t03his text is l04ots of colors a09,07nd other burk c0odes
var %substring = $mid($strip(%string),$pos($strip(%string),ex),9)
; what goes in here to get to below!
;
t03his t!!!this-chunk-missing!!!ts of colors a09,07nd other burk c0odes

The true %substring's are actually defined by a set or rules based apon the contents of the text (stripped) , some are between certain [ ] or ( ) orhers in certain positions etc, but the continuing factor through all of it is that any burk codes may appear anywhere in the unstripped string.

Joined: Dec 2002
Posts: 208
C
Fjord artisan
Offline
Fjord artisan
C
Joined: Dec 2002
Posts: 208
sorry i read through your request fast and didnt catch all the details,

this should do what you want, it can be simplified quite a bit but it this way its easier to see how things work.

Code:
strange.request {
  ; replaces $2 with $3 in $1
  var %str = $1, %str2 = $strip(%str)
  var %substr = $2, %replacement = $3
  var %pos1 = $pos(%str2,%substr,1)
  var %cnt1 =  $count($left(%str2,%pos1),$left(%substr,1))
  var %pos2 = $calc(%pos1 + $len(%substr) - 1)
  var %cnt2 =  $count($left(%str2,%pos2),$right(%substr,1))
  var %real.pos1 = $pos(%str,$left(%substr,1),%cnt1)
  var %real.pos2 = $pos(%str,$right(%substr,1),%cnt2)
  return $+($left(%str,$calc(%real.pos1 - 1)),%replacement,$right(%str,$+(-,%real.pos2)))
}


$strange.request(string,substring,replacetext)

hope this is more helpful

basicly what it does it it locates the posision of the first and last chr of substr in the original string, then splices the replacment text between what exists to the left and right of thos posisions

Cobra^

Joined: Jan 2003
Posts: 2,523
Q
Hoopy frood
Offline
Hoopy frood
Q
Joined: Jan 2003
Posts: 2,523
Not sure if this is what you wanted but try it:
Code:
repl {
  var %s = (?:[]|(?:\\d\\d?(?:,\\d\\d?)?)?)*
  !.echo -q $regsub($2,/(?<=.)(?=.)/g,%s,%s) $regsub($1,$+(/,%s,/gi),$replace($3,\,\\,$,\$),%s)
  return %s
}
Usage is $repl(input string,before text,after text)
Example: //var %string = t03his text is l04ots of colors a09,07nd other burk c0odes | echo -a %string | echo -a $repl(%string,colors,COLORS)

$repl()'s limitation is that the second param ("before text") must not contain any regex special character (like \, +, ?, * etc). If you don't like this, you can use $replex(); that huge $replace() in it takes care of the special chars.
Code:
replex {
  var %s = (?:[]|(?:\\d\\d?(?:,\\d\\d?)?)?)*, %2 = $&
    $replace($2,\,\\,^,\^,$,\$,.,\.,[,\[,$chr(40),\ $+ $chr(40),$chr(41), $&
    \ $+ $chr(41),?,\?,*,\*,+,\+,$chr(123),\{,$chr(125),\})
  !.echo -q $regsub(%2,/(?<=.)(?=.)/g,%s,%s) $regsub($1,$+(/,%s,/gi),$replace($3,\,\\,$,\$),%s)
  return %s
}


/.timerQ 1 0 echo /.timerQ 1 0 $timer(Q).com
Joined: Jan 2003
Posts: 2,523
Q
Hoopy frood
Offline
Hoopy frood
Q
Joined: Jan 2003
Posts: 2,523
Hehe you sumbitted you post while I was previewing mine, and it turns out we made the same alias. Nice one btw and since it makes no use of regex, it might be faster too (if you optimize it, like you said) smile


/.timerQ 1 0 echo /.timerQ 1 0 $timer(Q).com
Joined: Sep 2003
Posts: 4,230
D
DaveC Offline OP
Hoopy frood
OP Offline
Hoopy frood
D
Joined: Sep 2003
Posts: 4,230
Excellent, Cobra almost had it with his, but it fell over on substrings begining or ending in numbers, as the color codes had these in and would cause a missmatch in locating the start and end of the substring, but it was a clever laterally thought of idea i felt.


I had a feeling it would be a regex using the substring with the regex for any possable burk codes mixed in, but it was well beyond my knowledge of what to put in there. great to see it was doable.


I did need the $REPLEX but it wasnt working quite right
When the replace was done the first regsub was inserting the burk code (%s) regex between each character so * replaced with \* ended up getting one in between the \ & * etc

I fixed that pretty easy (see below incase you can improve it) now its running perfectly, at a rate 10 times faster than my original code.

Code:
replext {
  var %SubString = $2
  !.echo -q $regsub(%SubString,/(?<=.)(?=.)/g,$chr(26),%SubString)
  var %SubString = $replace(%SubString,\,\\,^,\^,$,\$,.,\.,[,\[,$chr(40),\ $+ $chr(40),$chr(41),\ $+ $chr(41),?,\?,*,\*,+,\+,$chr(123),\{,$chr(125),\})
  var %burkcodes = (?:[]|(?:\d\d?(?:,\d\d?)?)?)*
  var %SubString = $replace(%SubString,$chr(26),%burkcodes)
  var %ResultString
  !.echo -q $regsub($1,$+(/,%SubString,/gi),$replace($3,\,\\,$,\$),%ResultString)
  return %ResultString
}   
 


Thanks for the help with this, I must really get into regex more as it would appear to be able to solve several complexe problems very quickly.

Also thanks to Cobra and Iori (who was helping in email) for there greatfully accepted input on this.

Joined: Jan 2003
Posts: 2,523
Q
Hoopy frood
Offline
Hoopy frood
Q
Joined: Jan 2003
Posts: 2,523
Ah you're right, I totally overlooked that problem. Your fix is fine, I'd use the same method. I'd probably use $cr instead of $chr(26), as the former cannot be part of an IRC message. As for optimization, there's not much to do, except minimize the usage of intermediate variables. Here's how I'd write it (I also added | as a special character, which for some reason I forgot to do before; and removed } from the special chars list, since } is special only if there is a { before)
Code:
replext {
  var %a
  !.echo -q $regsub($2,/(?<=.)(?=.)/g,$cr,%a)
  %a = $replace(%a,\,\\,^,\^,$,\$,.,\.,[,\[,$chr(40),\ $+ $chr(40),$chr(41), $&
    \ $+ $chr(41),?,\?,*,\*,+,\+,$chr(123),\{,|,\|,$cr,(?:[]|(?:\d\d?(?:,\d\d?)?)?)*)
  !.echo -q $regsub($1,$+(/,%a,/gi),$replace($3,\,\\,$,\$),%a)
  return %a
}


/.timerQ 1 0 echo /.timerQ 1 0 $timer(Q).com
Joined: Sep 2003
Posts: 4,230
D
DaveC Offline OP
Hoopy frood
OP Offline
Hoopy frood
D
Joined: Sep 2003
Posts: 4,230
Thanks for the update, and suggestion on using $cr, i never seen a eof in a line so have been using that, i ran the script through a bunch of test strings and it came out flying, then i put it in the actual code, and wouldnt you know it...
* String too long: $replace
It couldnt reliably deal with substrings over 26 characters, with each one getting a possable 2 charcter replacement and a 34 character regex the line just over shot the max length real quick.
I solved it pretty well, i just chopped the substring up. and replaced it in parts.

heres the code, I didnt do a few of the qother tweaks as i might have to come back one day to this, and if its tweaked up to the max, ill be going, What?!?!?! whats this doing that for etc etc.

%TIM.RawLine is original colorized text
%TIM.Trigger is the complete substring text

Code:
 
    if ($pos(%TIM.RawLine,%TIM.Trigger) == $null) {
      ;  *** BURK codes in the trigger, So isolate trigger and replace with non BURK coded trigger *
      var %TIM.Counter = 1
      while ($mid(%TIM.Trigger,%TIM.Counter,20)) {
        var %TIM.SubString = $ifmatch
        if (%TIM.Counter != 1) var %TIM.SubString = $lf $+ %TIM.SubString
        !.echo -q $regsub(%TIM.SubString,/(?<=.)(?=.)/g,$cr,%TIM.SubString)
        var %TIM.SubString = $replace(%TIM.SubString,\,\\,^,\^,$,\$,.,\.,[,\[,$chr(40),\ $+ $chr(40),$chr(41),\ $+ $chr(41),?,\?,*,\*,+,\+,$chr(123),\{,$chr(125),\},|,\|)
        var %TIM.BurkCodes = (?:[]|(?:\d\d?(?:,\d\d?)?)?)*
        var %TIM.SubString = $replace(%TIM.SubString,$cr,%TIM.BurkCodes)
        !.echo -q $regsub(%TIM.RawLine,$+(/,%TIM.SubString,/gi),$lf,%TIM.RawLine)
        inc %TIM.Counter 20
      }
      var %TIM.RawLine = $replace(%TIM.RawLine,$lf,%TIM.Trigger)
    }

    var %TIM.Hotlink.Trigger =  $+ $replace(%TIM.Trigger ,$chr(160),$chr(26) ,$chr(32),$chr(160) ,$chr(26),$str($chr(160),2)) $+ 
    echo -itlbfmr $1 < $+ $1 $+ > $replace(%TIM.RawLine,%TIM.Trigger,$chr(32) $+ %TIM.Hotlink.Trigger $+ $chr(32))


The last two lines are what i do with the substring/triggering text, I replace the original with one surrounded buy a space & double bold also inside it spaces are replaced with hardspaces, which makes it all one word, I then elsewhere can setup ON HOTLINK events on the text, its being used for fileserver triggers currently, but i also wanted it for some other things i want to implement.


Link Copied to Clipboard