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 "<".
 
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)" );
 
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.
 
That's not the problem. The problem is that there might be bolded text before the name of the item.
 
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)
 
Oh right, I misunderstood Jason's remark.
This specifically solves the <i>...</i> problem:
Code:
<b>([^<]*(?:<i>[^<]*</i>[^<]*)?)</b> moved from case to inventory
 
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:
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
 
Implemented in r975, with xKiv's RegEx:
Code:
<b>(([^<]*((?!</b>)<))*[^<]*)</b> moved from inventory to case
 
Back
Top