mIRC Home    About    Download    Register    News    Help

Print Thread
Page 1 of 2 1 2
#27440 01/06/03 04:17 PM
Joined: May 2003
Posts: 730
S
ScatMan Offline OP
Hoopy frood
OP Offline
Hoopy frood
S
Joined: May 2003
Posts: 730
//var %x | .echo -q $regsub(blahblah,/^.(.)|(.).$/g,4\1,%x) | echo -a %x
i know i can do that with $right $left and $mid but i want to do it with regex so it will make the second letter with color and the second letter before the end, the problem is that it doesn't show the first letter and last
any ideas??

#27441 01/06/03 07:38 PM
Joined: Feb 2003
Posts: 2,812
Hoopy frood
Offline
Hoopy frood
Joined: Feb 2003
Posts: 2,812
Took me a little bit to figure this one out.

The reason why it's excluding the first and last characters, is because they weren't included in your back-reference. $regsub replaces the entire substring that is matched, including characters that fall outside of the back-reference. Since you replaced the entire substring with only the characters from the back-reference, the first and last characters got "written over".


Well. At least I won lunch.
Good philosophy, see good in bad, I like!
#27442 01/06/03 08:00 PM
Joined: Feb 2003
Posts: 2,812
Hoopy frood
Offline
Hoopy frood
Joined: Feb 2003
Posts: 2,812
Its not as pretty, but this is the best I can come up with for a single expression.
var %x = abcdefg
var %cnt = $regsub(%x,/^(.)(.)(.*)(.)(.)$/g,\104\2\304\4\5,%x)
echo -a %x


Well. At least I won lunch.
Good philosophy, see good in bad, I like!
#27443 01/06/03 08:07 PM
Joined: Dec 2002
Posts: 2,809
C
Hoopy frood
Offline
Hoopy frood
C
Joined: Dec 2002
Posts: 2,809
Well that does what his code said, but it doesn't do what his text said. He did say "letter" not "character" . matches any character, [[:alpha:]] matches any letter. But perhaps he just misspoke...

#27444 01/06/03 08:10 PM
Joined: Feb 2003
Posts: 2,812
Hoopy frood
Offline
Hoopy frood
Joined: Feb 2003
Posts: 2,812
He specified '.' in his original expression, which I'm sure he understands as 'anycharacter', if he already knows about ^ and $. I'm not one to monkey with the character class someone chooses unless I see specific reason to.

- Raccoon


Well. At least I won lunch.
Good philosophy, see good in bad, I like!
#27445 01/06/03 08:27 PM
Joined: May 2003
Posts: 730
S
ScatMan Offline OP
Hoopy frood
OP Offline
Hoopy frood
S
Joined: May 2003
Posts: 730
codemastr, no i mean character, i said 'letter' becuz the text that given to the regular expression contains only letters.
Raccoon thanks, can u explain me a little about it? i just can't figured it out how it works and i don't really know what is \2 \3 \4 \5.



Last edited by ScatMan; 01/06/03 08:29 PM.
#27446 01/06/03 08:35 PM
Joined: Feb 2003
Posts: 2,812
Hoopy frood
Offline
Hoopy frood
Joined: Feb 2003
Posts: 2,812
In your original expression, notice how you used 4\1. This meta-character represents the first back-reference in your regular expression (the contents of ()). Subsequent back-references are referenced by \2 \3 \4 \5 and so on.

It works by saving the first character to \1, the second to \2, the last character to \5, the second-to-last to \4, and everything inbetween ((.*) == 0 or more AnyCharacters) to \3.

- Raccoon


Well. At least I won lunch.
Good philosophy, see good in bad, I like!
#27447 01/06/03 08:37 PM
Joined: Dec 2002
Posts: 2,809
C
Hoopy frood
Offline
Hoopy frood
C
Joined: Dec 2002
Posts: 2,809
One thing to add about backreferencing, it's called an "NP-Complete" programming problems, which basically means, it is slow as hell. Therefore, if you can avoid using it (such as when you said you could just use $left $right and $mid) then you definately should.

#27448 01/06/03 08:42 PM
Joined: Feb 2003
Posts: 2,812
Hoopy frood
Offline
Hoopy frood
Joined: Feb 2003
Posts: 2,812
Agreed. I even imagine using two expressions may be slightly faster.

var %x = abcdefg
var %cnt = $regsub(%x,/^.(.)/,4\1,%x)
var %cnt = $regsub(%x,/(.).$/,4\1,%x)
echo -a %x

All three methods are probably worthy of a speed test. I'll try this later today and post the results.


Well. At least I won lunch.
Good philosophy, see good in bad, I like!
#27449 01/06/03 08:43 PM
Joined: May 2003
Posts: 730
S
ScatMan Offline OP
Hoopy frood
OP Offline
Hoopy frood
S
Joined: May 2003
Posts: 730
btw, what's back-reference ?? smirk

#27450 01/06/03 08:48 PM
Joined: Feb 2003
Posts: 2,812
Hoopy frood
Offline
Hoopy frood
Joined: Feb 2003
Posts: 2,812
the contents of ().

In your expression, its what allows you to capture a character and use it later.


Well. At least I won lunch.
Good philosophy, see good in bad, I like!
#27451 01/06/03 08:57 PM
Joined: May 2003
Posts: 730
S
ScatMan Offline OP
Hoopy frood
OP Offline
Hoopy frood
S
Joined: May 2003
Posts: 730
ohhhhh, hmm wait a sec

#27452 01/06/03 09:11 PM
Joined: May 2003
Posts: 730
S
ScatMan Offline OP
Hoopy frood
OP Offline
Hoopy frood
S
Joined: May 2003
Posts: 730
ohhhhhhh i get it!!
and i get also that u don't need the //g in this Regex smile


#27453 01/06/03 09:15 PM
Joined: Feb 2003
Posts: 2,812
Hoopy frood
Offline
Hoopy frood
Joined: Feb 2003
Posts: 2,812
correct. smile


Well. At least I won lunch.
Good philosophy, see good in bad, I like!
#27454 01/06/03 10:31 PM
Joined: Jan 2003
Posts: 2,523
Q
Hoopy frood
Offline
Hoopy frood
Q
Joined: Jan 2003
Posts: 2,523
The problem with this solution is that if the 3rd (or last) character is a number it will mess up, because the two terminating ^K's would actually start another colour. To see what I mean, try your regex with "ab3def7".

The simplest workaround would be this:
Code:
$regsub(%x,/^(.)(.)(.*)(.)(.)$/g,$+(\104\2,$str($chr(2),2),\304\4,$str($chr(2),2),\5),%x)
We insert ^B pair after the terminating ^K, preventing it from colouring anything we don't want. I made it with $str(...) so that it's more readable.

Another thing, this code only works with a single word; it can't be used to colour the letters in each words, in a string like "hello world!". To do so, and also get rid of some backreferences, the $regsub() should look like this:
Code:
$regsub(%x,/(?<=^\S| \S)(\S)(\S*)(\S)(?=\S$|\S )/g,04\1\204\3,%x)
I know he didn't ask for help about code that works with a sentence and not just a word, I just couldn't help writing this version too :tongue:

However, this way a ^B pair is inserted even when there is no need to (because the 3rd or last char is not a number, so ^K would really be considered a terminating code). It is possible to check exactly this though, and not add a ^B when it's not necessary. Here's what I came up with:
Code:
alias color2chars {
  var %a = /(?<=^\S| \S)(\S)(\d?)(\S*)(\S)(?:(\d)()|()(\S))(?=$| )/g
  if $regsub($1,%a,$+(04\1,$cr,\2,$lf,\304\4,$cr,\5,$lf,\6),%a) {
    return $replace($remove(%a,$crlf,$lf),$cr,)
  }
  return $1
}
The $cr's and $lf's are used as temporary boundaries/signposts. I chose the two safest chars IRC-wise (they cannot be part of an IRC message so it's very unlikely that the user would even want to feed that $regsub() with a word that contains those chars). The regex pattern may look a bit odd but I made it so to avoid a 2nd $regsub() call and only use $replace()/$remove().

There's always a trade-off: the first way is faster, as it only calls one $regsub(), but produces an "imperfect" string, ie one that may contain redundant ^B pairs. The second way is slower since it calls a more complex $regsub() and a $replace()/$remove(), but produces a perfect result. So I guess it depends on where it's going to be used: if it's for an on INPUT or something, where the alias would be called once, I'd go for the 2nd way. If the alias is going to be called a lot of times (fex inside a loop), I'd choose the 1st.


/.timerQ 1 0 echo /.timerQ 1 0 $timer(Q).com
#27455 01/06/03 10:37 PM
Joined: Dec 2002
Posts: 2,809
C
Hoopy frood
Offline
Hoopy frood
C
Joined: Dec 2002
Posts: 2,809
Maybe I'm blind, but your regex returned exactly the same thing that his did.

#27456 01/06/03 10:45 PM
Joined: May 2003
Posts: 730
S
ScatMan Offline OP
Hoopy frood
OP Offline
Hoopy frood
S
Joined: May 2003
Posts: 730
uh
thanks
(yeah i know about the color thing that i need to do the number in a double digit format)

#27457 01/06/03 11:03 PM
Joined: Jan 2003
Posts: 2,523
Q
Hoopy frood
Offline
Hoopy frood
Q
Joined: Jan 2003
Posts: 2,523
No, the double-digit format, even though it should definitely be used too, has nothing to do with the problem I described. I'm afraid I cannot explain it much better than my previous post...


/.timerQ 1 0 echo /.timerQ 1 0 $timer(Q).com
#27458 01/06/03 11:03 PM
Joined: Jan 2003
Posts: 2,523
Q
Hoopy frood
Offline
Hoopy frood
Q
Joined: Jan 2003
Posts: 2,523
Did you try it with the example string I mentioned in my post? Here's a command with Raccoon's original code:
//var %x = ab3def7 | !.echo -q $regsub(%x,/^(.)(.)(.*)(.)(.)$/g,\104\2\304\4\5,%x) | echo -s %x

here's the 1st way it should be modified:
//var %x = ab3def7 | !.echo -q $regsub(%x,/^(.)(.)(.*)(.)(.)$/g,$+(\104\2,$str($chr(2),2),\304\4,$str($chr(2),2),\5),%x) | echo -s %x

Also try //echo -s $color2chars(ab3def7)


/.timerQ 1 0 echo /.timerQ 1 0 $timer(Q).com
#27459 01/06/03 11:17 PM
Joined: Dec 2002
Posts: 2,809
C
Hoopy frood
Offline
Hoopy frood
C
Joined: Dec 2002
Posts: 2,809
Ah I used the wrong $regsub, however your "simplest workaround" is not the simplest:

$regsub(%x,/^(.)(.)(.*)(.)(.)$/g,\104\299\304\499\5,%x)
That works just as good since color code 99 is equivilent to "normal text color"

Page 1 of 2 1 2

Link Copied to Clipboard