mIRC Home    About    Download    Register    News    Help

Print Thread
#229632 12/02/11 02:52 AM
Joined: Jul 2006
Posts: 248
B
bwuser Offline OP
Fjord artisan
OP Offline
Fjord artisan
B
Joined: Jul 2006
Posts: 248
Hey guys, I'm having a little trouble getting a regsubex replace working. I have a color script that colors my text. I want to modify it so that I can be typing in say green, and change a portion to red. Here's an example: greentext@red(redtext)greentext. The actual text would show up as greentextredtextgreentext but the colors would be green-red-green.

Currently the regsubex I'm using is
Code:
 $+ %text.color $+ $regsubex($1-,@([^$chr(40)]*)($chr(40)(.*?)$chr(41))/g, $+ 04$chr(44)01 $+ \3 $+  $+ 09$chr(44)01)

Where %text.color = 09,01. Now, I have the $chr's in there as escapes, since mirc didn't want to take
Code:
@([^\(]*)(\((.*?)\))
because of the parentheses.

I'm just wondering if anyone can point out a reason why this might not work. It stopped giving me "Invalid format: $regsubex" after I replaced the invalid characters with $chr's, but even though the code is valid in all of the regex testers that I've tried it still doesn't work. I know this is kinda convoluted, so feel free to ask any clarifying questions if you have them.

bwuser #229639 12/02/11 08:05 AM
Joined: Jul 2007
Posts: 1,129
T
Hoopy frood
Offline
Hoopy frood
T
Joined: Jul 2007
Posts: 1,129
Try this:
Code:
alias testing {
  echo -a $+($chr(3),9,$chr(44),1) $+ $regsubex($1-,/(.*?)(\100).+?\50(.*?)\51/,$&
    $+($chr(3),3,\1,$chr(3),4,\2,$chr(3),3,$+($chr(40),$+($chr(3),4,\3,$chr(3),3),$chr(41))))
}
I know there may be better approaches with this, but this should work as intended.
Code:
/testing greentext@red(redtext)greentext

Tomao #229659 12/02/11 11:53 PM
Joined: Jul 2006
Posts: 248
B
bwuser Offline OP
Fjord artisan
OP Offline
Fjord artisan
B
Joined: Jul 2006
Posts: 248
Thanks Tomao. Unfortunately, this results in the text "greentext@(redtext)greentext" where the @ and "redtext" are red but everything else is green. My frustration here is that the regex pattern works when tested via other methods, but there has to be something in the syntax that is illegal for me to use here.

bwuser #229673 13/02/11 05:28 AM
Joined: Feb 2006
Posts: 546
J
Fjord artisan
Offline
Fjord artisan
J
Joined: Feb 2006
Posts: 546
your problem was a simple one:

Originally Posted By: bwuser
$+ %text.color $+ $regsubex($1-,@([^$chr(40)]*)($chr(40)(.*?)$chr(41))/g, $+ 04$chr(44)01 $+ \3 $+  $+ 09$chr(44)01)


the parts in red (and, in fact, the entire surrounding expression) is treated as plaintext by mIRC - this follows from the basics of mIRC syntax. the expression "@([^$chr(40)]*)($chr(40)(.*?)$chr(41))/g" gets passed to the regex engine and, because of the plaintext $chr()s, cannot possibly match any string.

you can solve this any numbers of ways, the simplest of which is to just throw an extra ) into your original expression:

Code:
@([^()]*)(\((.*?)\))


now your parentheses are balanced and you can put that expression into $regsubex() without any trouble. obviously, the meaning of the expression has changed slightly, in that a ')' in between '@' and '(' is no longer acceptable. if you do expect this to appear in $1- and you don't want the meaning changed, you can use the following expression functionally equivalent to the one in your post:

Code:
@([^\(]*\)?)(\((.*?)\))


as you can see, the \)? serves little purpose; it's just there to ensure balanced parentheses.

also, you have errors in your substitution text. you'll notice it after testing a working expression, nothing that moving a few $+s won't sort out


"The only excuse for making a useless script is that one admires it intensely" - Oscar Wilde
jaytea #229684 14/02/11 12:18 AM
Joined: Jul 2006
Posts: 248
B
bwuser Offline OP
Fjord artisan
OP Offline
Fjord artisan
B
Joined: Jul 2006
Posts: 248
Thanks jaytea. This is exactly what I was looking for. I don't forsee ever having a closing parenthesis between the @ symbol and opening parenthesis as that space will be occupied by a color, so your fix isn't a problem. I also fixed the subtext so it properly displays without the $chr(44)01.
There's one more question I have. Would it be possible to modify the regsubex so that I can do multiple colors? Like have the ability to do @red() or @blue(). I know I could do some sort of extended set of if statements, using regex to match the word in between the @ and opening parenthesis, but is that the only way?

Last edited by bwuser; 14/02/11 12:26 AM.
bwuser #229689 14/02/11 09:31 AM
Joined: Feb 2006
Posts: 546
J
Fjord artisan
Offline
Fjord artisan
J
Joined: Feb 2006
Posts: 546
sure, you could quite easily match (\w+) in between '@' and '(', then use $findtok() etc. to map the colour name to its colour code.

see, once you start throwing new colours in the mix - allowing a variety of colours in the middle of a variety of other colours - you're going to run into problems when it comes to colour preservation, since you can't always revert back to green once the new coloured text has been substituted in.

there is a solution to this which also lends itself quite nicely to support for nested colour groups. you can use a single regular expression to find the dominant foreground & background colours (if any) before the next @colour() group, then match the group according to a specific set of rules. when you substitute the text back in, you can then append the colour codes you saved to have it revert back to the correct colours:

Code:
alias @colour {

  var %cols =                      $&
    white                       |( $&
    black                       |( $&
    (?:navy|dark)blue|navy      |( $&
    green                       |( $&
    red                         |( $&
    burgundy|brown              |( $&
    purple                      |( $&
    orange                      |( $&
    yellow                      |( $&
    lime|(?:l|br)ightgreen      |( $&
    teal|turqoise               |( $&
    aqua|(?:l|br)ightblue       |( $&
    (?:royal)?blue|royal        |( $&
    pink|fuchsia                |( $&
    gr[ea]y                     |( $&
    silver                         $&
    )))))))))))))))

  var $&
    %tx = $1                                                                           , $&
    %re = /^ (?|\x03(\d\d?)(?:,(\d\d?))?|[\x03\x0F]()()|.)*? (?(1)|())(?(2)|())          $&
    	  \K @ (?=\w*(\(((?>(?5)|[^()])*?)\))) ( %cols ) \5 /xi                        , $&
    %sb = $eval( $+($chr(3), $fix($calc(\0 - 5)), $iif(\2 != $null, $chr(44) $+ 99),     $& 
          \4$chr(3), $fix($int(\1 99)), $iif(\2 != $null, $chr(44) $+ $fix(\2))) , 0)

  while ($regsubex(col, %tx, %re, [ %sb ] ) != %tx) %tx = $v1

  return %tx
}

alias -l fix return $mid(0 $+ $1, -2)


%cols contains the names of colours ordered exactly as they appear in the colour palette. you may modify that list to reflect your personal naming convention, i've just thrown mine in for fun ;P if you do change them, don't add any (capturing groups) since that'll affect the rest of the code. stick to (?:non-capturing groups) as in (?:navy|dark).

so, because of the while loop, you can now nest your groups:

Code:
//echo -a $@colour(4red text @blue(blue text @red(more red!) back to blue @orange(some orange)) red text preserved)


Quote:

red text blue text more red! back to blue some orange red text preserved


"The only excuse for making a useless script is that one admires it intensely" - Oscar Wilde

Link Copied to Clipboard