About Us
Products
Purchase
Downloads
Support
Forums
Contact Us
Site
 Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » CMUD General Discussion
shalimar
GURU


Joined: 04 Aug 2002
Posts: 4734
Location: Pensacola, FL, USA

PostPosted: Thu Mar 15, 2012 3:49 pm   

%replace exclusions
 
The mud i am playing sends items in a given place all as one string, so i separate out the individual items like so

$items=%replace(%replace(%1, ", ", "|"), " and ", "|")

However, some items have the " and " in them as well, is there a way i can test what the words on either side of the word 'and' are before stripping it out of the string?

a leather and lace corset != a leather|lace corset
_________________
Discord: Shalimarwildcat
Reply with quote
Daern
Sorcerer


Joined: 15 Apr 2011
Posts: 809

PostPosted: Thu Mar 15, 2012 6:07 pm   
 
If I understand right, the list looks something like this: a, b, c and d ? Just replace the commas first, then the and will always be in the last item of the list, so only replace the and on that one. It won't be perfect, it would still mess up if the last item in the list actually has the word and in it, but I don't think there's anything that can be done about that.
Reply with quote
Rahab
Wizard


Joined: 22 Mar 2007
Posts: 2320

PostPosted: Thu Mar 15, 2012 7:56 pm   
 
If you want to test for specific words, you could use %match(), or %begins() and %ends().

If you want to split off the words on either side of "and" so that you can do some more complicated testing, you could use %match() to extract the words into variables.

Or you could use a #SUB to change things like "a leather and lace corset" into "a leather & lace corset".
Reply with quote
MattLofton
GURU


Joined: 23 Dec 2000
Posts: 4834
Location: USA

PostPosted: Thu Mar 15, 2012 11:22 pm   
 
In your replaces, replace phrases like " and a ", " and an", and " and some " first. This ensures that only the "and" that separates items is targeted.
_________________
EDIT: I didn't like my old signature
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Thu Mar 15, 2012 11:49 pm   
 
The easiest way to do this, in my opinion, is this:

Code:
$items = %replace(%1,", ","|")
$var = %item($items,%numitems($items))
$var = %replace($var," and ","|")
$items = %replaceitem($var,%numitems($items),$items)


It'll still screw up if the last item is 'a leather and lace corset', but you can add exceptions as you go along.
Reply with quote
shalimar
GURU


Joined: 04 Aug 2002
Posts: 4734
Location: Pensacola, FL, USA

PostPosted: Fri Mar 16, 2012 10:55 am   
 
And to implement the exception list?

I am finding some items that have commas as well, btw.
Will that affect the itemname's ability from being used as a %key in a dbVar?

Every item i find starts with either {a|an} or a word in %proper case.
_________________
Discord: Shalimarwildcat
Reply with quote
Rahab
Wizard


Joined: 22 Mar 2007
Posts: 2320

PostPosted: Fri Mar 16, 2012 2:15 pm   
 
Ugh. Ugly.

No, I don't think commas will interfere with usage as a key.

If every item does start with {a|an} or proper case, it should be possible to do it without an exception list. Use %pos() to find each instance of ", " or " and ", and check whether the remainder begins with "a " or "an " or [A-Z]. Off the top of my head, it might be something like:
Code:

$right = %1
$left = ""
$pos = %pos(", ", $right)
#WHILE ($pos) {
  $left = %concat($left, %left($right, $pos))
  $right = %right($right, ($pos + 2))
  #IF (%begins($right, "a ") OR %begins($right, "an ") OR %regex($right, "^[A-Z]*")) {
    $left = %concat($left, "|")
  } {
    $left = %concat($left, ", ")
  }
  $pos = %pos(", ", $right)
}
$right = $left
$left = ""
$pos = %pos(" and ", $right)
#WHILE ($pos) {
  $left = %concat($left, %left($right, $pos))
  $right = %right($right, ($pos + 5))
  #IF (%begins($right, "a ") OR %begins($right, "an ") OR %regex($right, "^[A-Z]*")) {
    $left = %concat($left, "|")
  } {
    $left = %concat($left, " and ")
  }
  $pos = %pos(" and ", $right)
}
$items = %concat($left, $right)


I _think_ something like that will work, but I'm not positive about concatenating stuff onto a stringlist. If that doesn't work (or if you want to be more robust against future changes in Cmud) then use something like "--SEPARATOR--" in %concat() instead of "|", and at the end just replace "--SEPARATOR--" with "|".

[edited to fix an error in the code]
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Fri Mar 16, 2012 5:55 pm   
 
Unfortunately, %regex($right, "^[A-Z]*") matches lowercase too, for some reason. At least, it did in my tests.

Code:
#PRINT %regex("Testing","^[A-Z]*") %regex("testing","^[A-Z]*")

returned 1 1 instead of 1 0, as should be expected.

Just a heads up that the %regex is apparently buggy.

Edit: For that matter...
Code:
#PRINT %regex("13","^[A-Z]*")

returned 1 as well. Something's definitely not right with %regex.

Edit 2: Changing %regex to %match worked, though.
Reply with quote
Daern
Sorcerer


Joined: 15 Apr 2011
Posts: 809

PostPosted: Fri Mar 16, 2012 6:38 pm   
 
There's nothing wrong with %regex, your patterns will match nothing, and therefore everything (does that make sense? Razz). Change the * to a + and it won't match.
EDIT: As for the case sensitivity, all regexes in CMUD are case insensitive, but case insensitivity can be disabled with (?-i), and re-enabled further on in the regex with (?i) if you want.
Reply with quote
Rahab
Wizard


Joined: 22 Mar 2007
Posts: 2320

PostPosted: Fri Mar 16, 2012 8:24 pm   
 
Bleh! Sorry, bad regex. Change the regex to "^[A-Z].*" Or use %match, as already suggested.
Reply with quote
shalimar
GURU


Joined: 04 Aug 2002
Posts: 4734
Location: Pensacola, FL, USA

PostPosted: Mon Mar 19, 2012 5:25 am   
 
hmm is there a way to make it include two|three|four|five|six|seven|eight|nine|ten without making that have a rediculous amount of ORs?
_________________
Discord: Shalimarwildcat
Reply with quote
Rahab
Wizard


Joined: 22 Mar 2007
Posts: 2320

PostPosted: Mon Mar 19, 2012 1:42 pm   
 
Hm. Maybe change the #IF to:
Code:

#IF (%match($right, "^{a|an|two|three|four|five|six|seven|eight|nine|ten} *" OR %match($right, "^[A-Z]*")) {
Reply with quote
shalimar
GURU


Joined: 04 Aug 2002
Posts: 4734
Location: Pensacola, FL, USA

PostPosted: Mon Mar 19, 2012 2:44 pm   
 
It seems to be spotting each item properly, but instead of inserting pipes, it is turning the start of each item into a comma, and dropping the last item entirely

Code:
an oiled leather thigh holster, a pin cushion, Sinuous Black Tail, a pair of vampire fangs

turns into
Code:
an oiled leather thigh holster,,  pin cushion,, inuous Black Tail,,


Oh, i converted the previous code into a function

Code:
<func name="itemList" id="194">
  <value>$right = %1
$left = ""
$pos = %pos( ", ", $right)
#WHILE ($pos) {
  $left = %concat( $left, %left( $right, $pos))
  $right = %right( $right, ($pos + 2))
  #IF (%match( $right, "^{a|an|two|three|four|five|six|seven|eight|nine|ten} *" OR %match( $right, "^[A-Z]*"))) {
    $left = %concat( $left, "|")
    } {
    $left = %concat( $left, ", ")
    }
  $pos = %pos( ", ", $right)
}
$right = $left
$left = ""
$pos = %pos( " and ", $right)
#WHILE ($pos) {
  $left = %concat( $left, %left( $right, $pos))
  $right = %right( $right, ($pos + 5))
  #IF (%match( $right, "^{a|an|two|three|four|five|six|seven|eight|nine|ten} *" OR %match( $right, "^[A-Z]*"))) {
    $left = %concat( $left, "|")
    } {
    $left = %concat( $left, " and ")
    }
  $pos = %pos( " and ", $right)
  }
$items = %concat( $left, $right)
#RETURN $items</value>
</func>
_________________
Discord: Shalimarwildcat
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Mon Mar 19, 2012 6:35 pm   
 
A couple minor changes. Rahab's +2 should have been +1, and the first $left = %concat should have ($pos-1). I've updated the function here:

Code:
<func name="itemList" id="1">
  <value>$right = %1
$left = ""
$List = ""
$pos = %pos( ", ", $right)
#WHILE ($pos) {
  $left = %concat( $left, %left( $right, ($pos-1)))
  #PRINT {$left}
  $right = %right( $right, ($pos + 1))
  #PRINT {$right}
  #IF (%regex( $right, "^{a|an|two|three|four|five|six|seven|eight|nine|ten} .*" OR %match( $right, "^[A-Z].*"))) {
    $left = %concat($left, "|")
    } {
    $left = %concat( $left, ", ")
    }
  $pos = %pos( ", ", $right)
}
$right = $left
$left = ""
$pos = %pos( " and ", $right)
#WHILE ($pos) {
  $left = %concat( $left, %left( $right, $pos))
  $right = %right( $right, ($pos + 5))
  #IF (%regex( $right, "^{a|an|two|three|four|five|six|seven|eight|nine|ten} .*" OR %regex( $right, "^[A-Z].*"))) {
    $left = %concat( $left, "|")
    } {
    $left = %concat( $left, " and ")
    }
  $pos = %pos( " and ", $right)
  }
$items = %concat( $left, $right)
#RETURN $items</value>
</func>


It worked in my test session, turning your original text into
Quote:
an oiled leather thigh holster|a pin cushion|Sinuous Black Tail|


I know there's a way to remove the trailing |, but I can't think of it right now.
Reply with quote
Rahab
Wizard


Joined: 22 Mar 2007
Posts: 2320

PostPosted: Tue Mar 20, 2012 12:02 am   
 
Hm. The reason Charneus code has a trailing pipe is because it is still dropping the last item.

Aha! I see the problem. After the first #WHILE, there is still some value of $right, which is be left out in the next #WHILE. Change the line
Code:
$right = $left

into
Code:
$right = %concat($left, $right)
Reply with quote
shalimar
GURU


Joined: 04 Aug 2002
Posts: 4734
Location: Pensacola, FL, USA

PostPosted: Tue Mar 20, 2012 2:23 am   
 
the last item is there, but the and is still on the last item, now with double spaces instead of single on either side

Code:
a close helm, Downy Soft Underfur, Whiskers, a small bold red scorpion, a pair of lion paws and a pair of black studded boots
to
a close helm|Downy Soft Underfur|Whiskers|a small bold red scorpion|a pair of lion paws  and  pair of black studded boots
_________________
Discord: Shalimarwildcat
Reply with quote
Rahab
Wizard


Joined: 22 Mar 2007
Posts: 2320

PostPosted: Tue Mar 20, 2012 3:53 pm   
 
One last correction:
Code:

$right = %right( $right, ($pos + 5))

should be
Code:

$right = %right( $right, ($pos + 4))
Reply with quote
shalimar
GURU


Joined: 04 Aug 2002
Posts: 4734
Location: Pensacola, FL, USA

PostPosted: Tue Mar 20, 2012 7:19 pm   
 
also found it needed
Code:
$left = %concat( $left, %left( $right, ($pos-1)))

But for some reason the final #IF test is sticking the and back on every time
_________________
Discord: Shalimarwildcat
Reply with quote
shalimar
GURU


Joined: 04 Aug 2002
Posts: 4734
Location: Pensacola, FL, USA

PostPosted: Tue Mar 20, 2012 7:32 pm   
 
Aha, its was just a brace in the wrong spot, fixed now.

Code:
<func name="itemList" id="194">
  <value>$right = %1
$left = ""
$List = ""
$pos = %pos( ", ", $right)
#WHILE ($pos) {
  $left = %concat( $left, %left( $right, ($pos-1)))
  $right = %right( $right, ($pos + 1))
  #IF (%regex( $right, "^{a|an|two|three|four|five|six|seven|eight|nine|ten} .*" OR %match( $right, "^[A-Z].*"))) {$left = %concat( $left, "|")} {$left = %concat( $left, ", ")}
  $pos = %pos( ", ", $right)
  }
$right = %concat( $left, $right)
$left = ""
$pos = %pos( " and ", $right)
#WHILE ($pos) {
  $left = %concat( $left, %left( $right, ($pos-1)))
  $right = %right( $right, ($pos + 4))
  #IF (%regex( $right, "^{a|an|two|three|four|five|six|seven|eight|nine|ten} .*") OR %regex( $right, "^[A-Z].*")) {$left = %concat( $left, "|")} {$left = %concat( $left, " and ")}
  $pos = %pos( " and ", $right)
  }
$items = %concat( $left, $right)
#PRINT {$items}</value>
</func>
_________________
Discord: Shalimarwildcat
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD General Discussion All times are GMT
Page 1 of 1

 
Jump to:  
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

© 2009 Zugg Software. Hosted by Wolfpaw.net