|
Zyphrus Newbie
Joined: 27 Mar 2004 Posts: 7
|
Posted: Mon Apr 02, 2007 6:49 pm
extracting letters of a certain color from a string |
this mud is uses scrambled codes for a certain action. the player has to extract all the characters which match the color of the last letter to get the code. Here is what I've got so far (it does not work yet) :
Code: |
The trigger:
You begin scanning a &monstername's digital code.$&code$
The script:
#if (%len( @code)<40) {#show "ERROR ERROR ERROR ERROR ERROR ERROR ERROR"} {
#var code %leftback( @code, 4)
#var a %match( @code, "(~%e~[[0-9,~;]m)?$", color)
#var color %replace( %quote( @color), "[", "~~~[")
#show "HELLO "@monstername @code
#var reduced %subregex( @code, @color, "")
} |
The trigger has Ansi Trigger checked. zMUD sometimes doesn't add the ansi codes to the string, the #if catches those cases. The string has the structure
color letter color ... letter color letter color
example :
%e[33ma%e[35mx%e[33ms%e[35m!%e[36mc%e[31m!%e[1;32ml%e[1;35m2%e[0mG%e[1;35mw%e[1;33mn%e[0;32ms%e[1;32m,%e[1;36m$%e[1;30mx%e[0;34mv%e[1;34mH%e[1;32m3%e[0m
the second last color is the color of the last letter. I'm able to put that color in a variable, and to add ~ to the [ and possible ; in that variable too. the %subregex doesn't work but is supposed to remove all the color codes in front of the letters I'm looking for. the second step would be to remove all remaining color codes and the letter right behind each
I tried both with the escaped and unescaped color code. I also tried different approaches to the second argument of the subregex, but it always either removed nothing or all color codes.
parsing the string character by character failed too because of the special characters it contains ( ; , ' @ / % . < > are possible letters for the code)
any help with getting this to work would be awesome !
Zyphrus |
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Mon Apr 02, 2007 10:43 pm |
The help is your friend. %stripansi
|
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
Zyphrus Newbie
Joined: 27 Mar 2004 Posts: 7
|
Posted: Mon Apr 02, 2007 11:21 pm |
I wish it were :( I'll try to explain the problem better: the mud displays a string of random characters (including non-letters), and you have to find all the ones which have the same color as the last letter. So you need the ANSI codes to determine whether to keep or drop each character
|
|
_________________ |
|
|
|
Guinn Wizard
Joined: 03 Mar 2001 Posts: 1127 Location: London
|
Posted: Tue Apr 03, 2007 12:58 am |
My attempt...
First just making sure the variables are empty
Code: |
colour = ""
char = ""
colours = ""
chars = "" |
Code: |
code = %replace("%e[33ma%e[35mx%e[33ms%e[35m!%e[36mc%e[31m!%e[1;32ml%e[1;35m2%e[0mG%e[1;35mw%e[1;33mn%e[0;32ms%e[1;32m,%e[1;36m$%e[1;30mx%e[0;34mv%e[1;34mH%e[1;32m3","%e[","|")
#NOOP %pop(code)
#FO @code {
#NOOP %match(%i,"(*)m(*)",colour,char)
colours = %push(@colour, @colours)
chars = %push(@char, @chars)
}
#LOOP %numitems(@chars) {
#IF (%item(@colours,%i) = %item(@colours,1)) {
#SAY %item(@chars,%i)
}
} |
To explain what it does. Uses %replace to throw everything into a string list, and removes the %e[ stuff from the start of each item. Then splits that list into two more lists of colours and chars, then compares the first colour (the last is now at the top because I was using %push to create the new lists) against each other colour and if they match it takes the corresponding item from the chars list
I think it works, assuming I understood what you want (namely you want to show the characters that match the colour of the last character?) |
|
_________________ CMUD Pro, Windows Vista x64
Core2 Q6600, 4GB RAM, GeForce 8800GT
Because you need it for text... ;) |
|
|
|
Arminas Wizard
Joined: 11 Jul 2002 Posts: 1265 Location: USA
|
Posted: Tue Apr 03, 2007 1:39 am |
For the trigger value
Captured=%leftback( %right( %replace( %replace( %replace( "%1", %e, "esc"), "esc[", "|"), ";", "_"), 1), 3)
words=%null
#forall @captured {#addkey words {%leftback( %i, 1)=%concat( %db( @words, %leftback( "%i", 1)), %rightback( "%i", 1))}}
To show the keys
#loopdb @words {#show %subchar( %key, "_", ";") %val}
Guinn beat me to it. |
|
_________________ Arminas, The Invisible horseman
Windows 7 Pro 32 bit
AMD 64 X2 2.51 Dual Core, 2 GB of Ram |
|
|
|
Zyphrus Newbie
Joined: 27 Mar 2004 Posts: 7
|
Posted: Tue Apr 03, 2007 9:51 am |
thanks for the solutions
I'm trying out both, to get to know the scripting language better. There's still a few things which seem strange. Like this :
Code: |
works :
%replace( %replace( "%2", %e, "esc"), "esc[", "|")
doesn't work :
%replace( "%2","%e[","|")
|
is it possible to fix the second version to do the replace in a single step? what is going wrong in the second case? |
|
|
|
Arminas Wizard
Joined: 11 Jul 2002 Posts: 1265 Location: USA
|
Posted: Tue Apr 03, 2007 1:24 pm |
It works a dandy in CMUD... I think it is an error in the parser somewhere so you can likely forget it. Sorry.
|
|
_________________ Arminas, The Invisible horseman
Windows 7 Pro 32 bit
AMD 64 X2 2.51 Dual Core, 2 GB of Ram |
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Tue Apr 03, 2007 3:53 pm |
That makes more sense now. Personally I don't think using either of those is too good of an idea since the seperator character "|" might possibly be a valid character. First thing I would say to do is turn off "Use [] for evaluation" and "Use <> for expansion" in the script parsing preferences. When enabled these 2 setting can cause odd results with complex parsing of characters such as what you describe.
Now to the script, just the stuff for inside the trigger.
#IF (%ends(%concat(%char(27),"[0m"),@Code)) {Code=%leftback(@Code,4)}
Seperator=%leftback(%rightback(@Code,10),1)
Seperator=%right(@Seperator,%eval(%pos(%char(27),@Seperator)-1))
FinalCode=""
#LOOP %numwords(@Code,@Seperator) {FinalCode=%concat(@FinalCode,%left(%word(@Code,%i,@Seperator),1))}
It might be possible to shorten out the first few lines with a neatly built %regex or %match. However the possibilty of getting the wrong match made me decide it is better to just locate the right ansi code by direct parsing. |
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
Zyphrus Newbie
Joined: 27 Mar 2004 Posts: 7
|
Posted: Tue Apr 03, 2007 4:36 pm |
My solution based on Arminas' approach works completely now, handling the special characters , ( ) % correctly. Also handles all cases of stripped redundant ansi color codes. Displays the final result with the original special characters. Below is the working script.
Thanks again, Guinn and Arminas !
Code: |
trigger :
You begin scanning a (*)'s digital code.$(*)$
script :
captured=%right( %replace( %replace( %replace( %replace( %replace( %replace( %replace( "%2", ",", "ä"), "%", "ö"), "(", "+"), ")", "-"), %e, "esc"), "esc[", "|"), ";", "_"), 1)
words=%null
modifier=0
#forall @captured {
#if (%i="0m") {} {
#if (%copy( %i, 2, 1) = "_") {
modifier=%copy( %i, 1, 1)
a = %i
} {#if (%left( %i, 2) = "0m") {
modifier=0
a=%i
} {a=@{modifier}_%i}}
x = %pos( "m", @a)
#addkey words {%left( @a, @x)=%concat( %db( @words, %left( @a, @x)), %right( @a, @x))}
color=%left( @a, @x)
}
}
#if (%len( %db( @words, @color, 1)) = 3) {hack %word( %1, 1) %replace( %replace( %replace( %replace( %replace( %db( @words, @color, 1), "ä", ","), "ö", "%"), "+", "("), "-", ")"), "_", ";")} {
#show ""
#show "code="%replace( %replace( %replace( %replace( %replace( %db( @words, @color, 1), "ä", ","), "ö", "%"), "+", "("), "-", ")"), "_", ";")
} |
|
|
_________________ |
|
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|