|
chris-74269 Magician
Joined: 23 Nov 2004 Posts: 364
|
Posted: Tue Mar 03, 2009 5:56 pm
Stripping ansi from part of a string |
I'm trying to strip ansi characters out of only part of a string, ideally I want to end up with a function where i do @stripansi(string,length) which will strip ansi ansi up the length I provide. However being as the ansi sequence captured would extend 3-5 characters and even moreso if there are multiple ansi sequences in the variable I'm having some trouble getting a script together. I would want to take something like:
Quote: |
%e[0S %e[1;33m@%e[0S-%e[1;36mO%e[0S-%e[1;36mO%e[0S-%e[1;36mO%e[0S %e[0m$
or
%e[0S %e[1;36mO%e[0S-%e[1;33m@%e[0S-%e[1;36mO%e[0S-%e[1;36mO%e[0S %e[0m$
|
And strip all ansi before the %e[1;33m(the @ in this example) and leave all ansi after it. I'm doing this because the location of the yellow @ or + or v is important and can only be determined by what character is yellow and a @/+/v/ect. I can't use a %stripansi to find the characters because there are other symbols that are also @/+/v which are not important on the same line. I started on a script that counted the number of escape sequences before the designated length and then tried to add the increased length, but it got a bit too convoluted and I'm hoping someone has a simpler solution. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Tue Mar 03, 2009 6:32 pm |
Umm, do you mean something like the existing %stripansi function?
|
|
|
|
Fang Xianfu GURU
Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Tue Mar 03, 2009 6:35 pm |
%stripansi - just cut the string into two parts, the part you want to have no ANSI codes and the part you want to leave alone. Use %stripansi on the relevant part and then join the string back together.
I'm currently having a ponder as to whether there's an easier way to go about this problem, though.
EDIT: Grr, I go for one cup of tea and Zugg beats me to it :( |
|
|
|
chris-74269 Magician
Joined: 23 Nov 2004 Posts: 364
|
Posted: Tue Mar 03, 2009 6:45 pm |
I can't do that because I can't get the actual length I need with splitting the string. Using the %stripansi wouldn't work as I said because the ansi is important to a certain point, if I used %strip ansi then a green @ and a yellow @ and a blue @ would all be the same, and there would be no way to determine which one was relevent. I can't cut the string into parts because the ansi codes are not consistent in how many will be present and thus the string length of what I want will vary. In general I think the easiest approach would be to use %regex() and get the location of \e[1;33m then work from there, but a function that would keep ansi after a certain position and strip it all before would be nice since I have other scripts that do things like capturing over lines that screw up because of a %e[0s being introduced and making my position off by 4.
|
|
|
|
Fang Xianfu GURU
Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Tue Mar 03, 2009 7:15 pm |
What do you mean "not consistent in how many will be present"? How are you obtaining this ANSI-laden string? If you're using a CMUD ANSI trigger, then CMUD will remove ANSI codes that don't actually change the colour - so you'll be left with only the codes that matter. Or do you mean that sometimes characters aren't accompanied by an ANSI code?
Essentially, your task is to divide the line up into individual characters and their ANSI sequences, if they have them. You loop through each character until you find the one that's yellow and then look at the number of characters you've processed so far - that number is the position of the character in the line.
I think this might be most easily accomplished - assuming the line contains no | characters - to use %subregex to put a | between each character. It'd look something like %subregex(%1,"((?:%e[[\d+;]+)?m.","\'1'|") and you can now use #forall to loop through each character, examining the colour number. Once you've got the number of the character in the string, you can %stripansi the whole string and get to work.
If the line does contain |s, just use %subchar to change them into something else while you work on them and then change them back afterwards. |
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Tue Mar 03, 2009 11:05 pm |
It sounds like all you need is %regex and %stripansi. Off the top of my head:
#LOCAL $PreYellow
#CALL %regex(@text,"(.*?)\033[1;33m", $PreYellow)
$PreYellow=%stripansi($PreYellow)
This gives you what you want because all you are looking for is before the first yellow coloring. If you really are looking for accumulating a specific number of characters then %subregex will be the way, but I would have to really think about the most efficient way to do it. |
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
chris-74269 Magician
Joined: 23 Nov 2004 Posts: 364
|
Posted: Wed Mar 04, 2009 4:22 am |
For my current instance what vijilante said works perfectly. What I wanted to use this same function for is a bit more tricky. Suppose I have strings that look like this:
Code: |
%ANSI#k%12345009BAB~test1%ANSI#k%12345015FFF~test2abc123%ANSI#k%12345%ANSI009BAB~test1%ansi#k%12345009BAB~test1
|
The part with 009,015, ect tells you how long the string following it will be. So currently my trigger captures the "(.*)\#k\%%d{5}(?strlength:%d){3}(?mipstring:.*)" part, (this sequence might be wrong since i'm just writing on the top of my head, but my actual one works and is similar to that. Then I take the strlength and take that many characters out of mipstring to use, then I want to return everything else. By returning everything else with #show this makes the function recursive so what I quoted would be parsed w/ 1 trigger. What screws it up is when the line gets so long it goes multiple lines or other funky situations which introduce ansi in the #k%12345xxxSTRING part. If I do mipstringa=%stripansi(@mipstring) then it will work fine, but it will strip the ansi from the part I want to echo back to my screen, because I can have a line like this:
Code: |
#k%12345009BAB~testaYou hit a mob really hard!!!!#k%12345009BAB~test2
|
The ansi is naturally added when I use #say to put the non-important information back to the screen, that is why I want to get a way to strip only part of the ansi. What I've been doing is doing a %regex on the string that is captured to see if an ansi character exists in @mipstringa and then getting the position of the escape sequence and the m and splicing that out, but sometimes it fails for reasons unknown to me. If an ansi sequence is left in there then the length which is extracted is too short and I get a line like: estaYou hit a mob really hard!!!
I guess you would really just have to play my mud and see the instances where this is screwing up, the mipsequence(#k%1235....) is sent w/o a carriage return or a line feed and sometimes it spans multiple lines when a lot of information is sent so this introduces a good deal of ansi from cmud adding %e[0S and %e[0m to the new lines. I would just parse for %e[0m/0S but I would much rather just make a function to work for any instance. I'll get back to the drawing board and post what I make for it and maybe we can go from there. |
|
|
|
Rahab Wizard
Joined: 22 Mar 2007 Posts: 2320
|
Posted: Wed Mar 04, 2009 5:54 pm |
Quote: |
I would just parse for %e[0m/0S but I would much rather just make a function to work for any instance. |
What other instances are you thinking of? I can't think of any, offhand. If the problem is the "%e[0m%e[0S" being inserted by Cmud, why don't you just remove those before the rest of your processing? |
|
|
|
chris-74269 Magician
Joined: 23 Nov 2004 Posts: 364
|
Posted: Wed Mar 04, 2009 11:09 pm |
As for other instances I can't think of any, as this is the first time I've ever needed to design such a function. However, the reason I didn't just remove the %e[0S/0m is because they may also be involved in the pattern which I want to echo back to the screen, so if those are stripped then the colors will not always be displayed as they were intended. What I've been working on is something like this (i'm not @ my home computer atm so this might not be 100% exact, but close enough)
function @ansistrip($string,$position)
$stripline=%left($string,$position)
#if ((%regex($stripline,"\e",$ansiposition)) {$ansiendposition=%regex(%right($string,$ansiposition),"m|S");$position=($ansiendposition-$ansiposition+$position);$stripline=%left($string,$position)} {#return $stripline}
If the first ansi escape sequence is found, then it goes right from that position until an m or an S is found, then the length of the ansi sequence is added to the position. I was then going to make the #if into a a #while, but for some reason I started getting infinite loop messages when i tried to do a #print $stripline to see how it was progressing. If anyone sees some obvious flaw in my logic please point it out or an easier way. |
|
|
|
Rahab Wizard
Joined: 22 Mar 2007 Posts: 2320
|
Posted: Thu Mar 05, 2009 3:39 pm |
[0S will not appear in ansi from the mud, since it is non-standard. It will only appear if it is inserted by Cmud.
|
|
|
|
|
|