|
Joined: May 2003
Posts: 730
Hoopy frood
|
OP
Hoopy frood
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??
|
|
|
|
Joined: Feb 2003
Posts: 2,812
Hoopy frood
|
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!
|
|
|
|
Joined: Feb 2003
Posts: 2,812
Hoopy frood
|
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!
|
|
|
|
Joined: Dec 2002
Posts: 2,809
Hoopy frood
|
Hoopy frood
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...
|
|
|
|
Joined: Feb 2003
Posts: 2,812
Hoopy frood
|
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!
|
|
|
|
Joined: May 2003
Posts: 730
Hoopy frood
|
OP
Hoopy frood
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.
|
|
|
|
Joined: Feb 2003
Posts: 2,812
Hoopy frood
|
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!
|
|
|
|
Joined: Dec 2002
Posts: 2,809
Hoopy frood
|
Hoopy frood
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.
|
|
|
|
Joined: Feb 2003
Posts: 2,812
Hoopy frood
|
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!
|
|
|
|
Joined: May 2003
Posts: 730
Hoopy frood
|
OP
Hoopy frood
Joined: May 2003
Posts: 730 |
btw, what's back-reference ??
|
|
|
|
Joined: Feb 2003
Posts: 2,812
Hoopy frood
|
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!
|
|
|
|
Joined: May 2003
Posts: 730
Hoopy frood
|
OP
Hoopy frood
Joined: May 2003
Posts: 730 |
|
|
|
|
Joined: May 2003
Posts: 730
Hoopy frood
|
OP
Hoopy frood
Joined: May 2003
Posts: 730 |
ohhhhhhh i get it!! and i get also that u don't need the //g in this Regex
|
|
|
|
Joined: Feb 2003
Posts: 2,812
Hoopy frood
|
Hoopy frood
Joined: Feb 2003
Posts: 2,812 |
correct.
Well. At least I won lunch. Good philosophy, see good in bad, I like!
|
|
|
|
Joined: Jan 2003
Posts: 2,523
Hoopy frood
|
Hoopy frood
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: $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: $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: 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
|
|
|
|
Joined: Dec 2002
Posts: 2,809
Hoopy frood
|
Hoopy frood
Joined: Dec 2002
Posts: 2,809 |
Maybe I'm blind, but your regex returned exactly the same thing that his did.
|
|
|
|
Joined: May 2003
Posts: 730
Hoopy frood
|
OP
Hoopy frood
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)
|
|
|
|
Joined: Jan 2003
Posts: 2,523
Hoopy frood
|
Hoopy frood
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
|
|
|
|
Joined: Jan 2003
Posts: 2,523
Hoopy frood
|
Hoopy frood
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
|
|
|
|
Joined: Dec 2002
Posts: 2,809
Hoopy frood
|
Hoopy frood
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"
|
|
|
|
|