Bug - Fixed Transfers supposedly fail for display case/inventory moves for items with "<" in name

Veracity

Developer
Staff member
Transfers supposedly fail for display case/inventory moves for items with "<" in name

Transferring from display case to inventory:

<b>Vial of <i>jus de larmes</i> (8)</b> moved from case to inventory.

Results in:

Transfer failed for Vial of <i>jus de larmes</i> (8)

Ditto for transfers in the other direction.

The transfers actually succeeded, but KoLmafia's model of inventory and the display case did not update correctly.

The following patterns in DisplayCaseRequest:

Code:
	public static final Pattern ITEM_PATTERN1 = Pattern.compile( "<b>([^<]*)</b> moved from inventory to case" );
	public static final Pattern ITEM_PATTERN2 = Pattern.compile( "<b>([^<]*)</b> moved from case to inventory" );
will not work well with items containing a "<".
 

matt.chugg

Moderator
I realise you probably only posted this to remind youself, but I though i'd ask if the below would work? not because i'm giving it to you as a fix, but because I want to know whether "what i'd do" would be right! :)

Code:
	public static final Pattern ITEM_PATTERN1 = Pattern.compile( "<b>(.*?)</b> moved from inventory to case" );
	public static final Pattern ITEM_PATTERN2 = Pattern.compile( "<b>(.*?)</b> moved from case to inventory" );

Code:
       public static final Pattern ITEM_PATTERNBOTH = Pattern.compile( "<b>(.*?)</b> (moved from case to inventory|moved from inventory to case)" );
 

jasonharper

Developer
Your versions of the patterns would match everything between the first "<b>" on the page, and the "</b> moved from..." text. They would only work if there was guaranteed to be no other bold text on the page.
 

Bale

Minion
That's not the problem. The problem is that there might be bolded text before the name of the item.
 

matt.chugg

Moderator
oh, I see! that explains the previous pattern! ok I need to see the source, will look when the server is down!

how about:

Code:
\b<b>(.*?)</b> (moved from case to inventory|moved from inventory to case)
 

slyz

Developer
Oh right, I misunderstood Jason's remark.
This specifically solves the <i>...</i> problem:
Code:
<b>([^<]*(?:<i>[^<]*</i>[^<]*)?)</b> moved from case to inventory
 

xKiv

Active member
Oh right, I misunderstood Jason's remark.
This specifically solves the <i>...</i> problem:
Code:
<b>([^<]*(?:<i>[^<]*</i>[^<]*)?)</b> moved from case to inventory

I would do
Code:
<b>([^<]*(?:<i>[^<]*</i>[^<]*)*)</b> moved from case to inventory
instead, in case of items with more than one italiziced part.
And maybe even
Code:
<b>([^<]*(<([a-zA-Z]*)>[^<]*</\\1>[^<]*)*)</b> moved from case to inventory
to handle any inner tags (including more <b>...</b>) - but still not nested tags.
Or maybe just
Code:
<b>(([^<]*((?!</b>)<))*[^<]*)</b> moved from case to inventory
which should handle everything except nested bees (<b>...<b>...</b>...</b>).

I think I can guarantee that you *can't* handle nested bees with a regex in this situation (unless you are satisfied with just an arbitrary pre-determined limit to the nesting, like, only one tag deep at most, like the example prior to this).


ETA @ matt:
adding word boundary condition doesn't help at all.
Regex matching will find the first position in the searched string at which the regex can match, and match there - it doesn't matter that it could find a shorter match at later position. It finds a match here, with the shortest possible inner match for the .*? part.
Code:
<b>something</b> lotsoftext <b>itemname</b> moved from case to inventory
will get matched from the first <b>
 
Last edited:

slyz

Developer
Or maybe just
Code:
<b>(([^<]*((?!</b>)<))*[^<]*)</b> moved from case to inventory
which should handle everything except nested bees (<b>...<b>...</b>...</b>).
That was exactly what I was trying to do when I gave up yesterday: find a way to tell the regex to keep looking until it met the first </b>, not until it met the first "</b> moved from case to inventory". I was trying to wrap my head around atomic grouping, to see if it could be helpful, but unsuccessfully.

Thanks for the insight on lookaheads.

Since the item name and quantity will still ge in group( 1 ), I guess there's no reason to make all of the other groups non-capturing, like this:
Code:
<b>((?:[^<]*(?:(?!</b>)<))*[^<]*)</b> moved from case to inventory
 

slyz

Developer
Implemented in r975, with xKiv's RegEx:
Code:
<b>(([^<]*((?!</b>)<))*[^<]*)</b> moved from inventory to case
 
Top