You are here:  » RegEx Alternative Matching Rules


RegEx Alternative Matching Rules

Submitted by ChrisNBC on Wed, 2016-07-06 11:35 in

Hi David,

A you know, I’m using RegEx matching on a few of my sites and have created a large number of rules (in excess of 10k per site). I wondered if you might be able to give me some advice on how I might resolve an issue I have encountered…

In summary I have some products where I match two elements to a narrow ‘mapping name’ using the RegEx rule below:

/(\b(ProductName1).+(ProductCode1)\b)/Ui

For some products the ProductCode1 element is not available so as an alternative I match using the Regex below which matches the productname and colour to an alternative (catch all) ‘mapping name’

/(\b(ProductName1).+(ProductColour)\b)/Ui

The problem is that for some products the product colour and ProductCode will both be available which means they are matched by both rules. I wondered if you could suggest if there is a way to match to rule one and then try to match to rule two only if the first is not found?

Would be grateful for any suggestions you might have.

Thanks in advance.

Best Regards
Chris

Submitted by support on Wed, 2016-07-06 12:24

Hi Chris,

When Product Mapping by RegExp is applied to a product at import time the loop breaks out after the first successful trigger / mapping, however the order in which they are applied is left down to the database since there is no ORDER BY clause on the selection SQL from the pt_productsmap_regexp table.

In /admin/ > Product Mapping by RegExp, existing mappings are ordered by name, so what you can do is expand this to order by name,id and apply the same to the selection at import time. That way, Product Mapping by RegExp rules will always be applied at import time in the same sequence as displayed during configuration.

To apply this, edit admin/productsmap_regexp.php and look for the following code at line 62:

  $sql = "SELECT * FROM `".$config_databaseTablePrefix."productsmap_regexp` ORDER BY name";

...and REPLACE with:

  $sql = "SELECT * FROM `".$config_databaseTablePrefix."productsmap_regexp` ORDER BY name,id";

And then in includes/admin.php look for the following code at line 567:

    $sql = "SELECT * FROM `".$config_databaseTablePrefix."productsmap_regexp`";

...and REPLACE with:

    $sql = "SELECT * FROM `".$config_databaseTablePrefix."productsmap_regexp` ORDER BY name,id";

Hope this helps!

Cheers,
David.
--
PriceTapestry.com

Submitted by jamie on Sun, 2016-09-18 11:08

Hi David,

"When Product Mapping by RegExp is applied to a product at import time the loop breaks out after the first successful trigger / mapping"

How would I need to change the code so that the regex engine would apply every formula I save in the Price Tapestry engine? The issue I'm running into is that the engine runs and matches my first formula, but then does not run any of the other formulas.

In pseudo code Im trying to make a for-each loop for every entry in the regex table but Im struggling to actually write the code!

Thanks very much for your help,
Jamie

Submitted by support on Mon, 2016-09-19 09:45

Hi Jamie,

If you look in includes/admin.php you'll find the break; statement that breaks out of the loop at the first successful match at line 344.

If you remove or comment out this statement, the code would then go on to test every other rule, the result being that last matched would be the one that applied.

Since only one rule should apply (and therefore why the code break;'s out of the loop once a match has been found) it might indicate that the rule should be constrained further to avoid multiple matches, as it might be incorrectly being applied. Apologies if i've mis-understood, let me know if you're still not sure of course...

Cheers,
David.
--
PriceTapestry.com

Submitted by jamie on Mon, 2016-09-19 11:51

Hi David,

I wasn't very clear, apologies. Basically what Im after is a way to apply more than one regex rule, instead of PT finding the first match and then breaking.

Let me give you an example. I have product names such as this:

Wetsuit (Ex Display) - Black - XS

I have 2 regex formulas:

1) Remove everything after the first hyphen >>> /^(.+?) - .+? - .+?/ >>>  $1
2) Remove everything after the first open-bracket >>> /^(.+) \(.+$/ >>>  $1

What is currently happening is that rule 1 executes, but then the regex-loop breaks and does not run rule 2. So the resulting product name becomes:

Wetsuit (Ex Display)

Instead of "Wetsuit" which I would expect.

So I wonder, what is the best way to make PT run all my regex rules?

Many thanks,
Jamie
ps. I completely get that changing the rule order above so that it removes everything after the open-bracket would work, but thats just one of many examples where the rule order wouldn't solve the issue.

Submitted by support on Mon, 2016-09-19 13:14

Hi Jamie,

If you had not already come across it, there is code for a Search and Replace RegExp filter in this comment - I'm wondering if it might be more appropriate in this scenario to do the "clean up" using a sequence of Search and Replace RegExp filters, followed by Product Mapping RegExp unmodified, assuming the single trigger / match scenario only...

Let me know if you're not sure how to construct the search patterns - delimiters and escaping where necessary should be used in the Search expression as the execution of the filter does not use preg_quote for maximum flexibility, or of course if you think it would still be more appropriate to modify Product Mapping by RegExp I'll try and point you in the right direction there...

Cheers,
David.
--
PriceTapestry.com

Submitted by jamie on Mon, 2016-09-19 15:39

Brilliant! A Global Search and Replace RegExp filter is exactly what I wanted. Thanks very much for your help David!

Submitted by jamie on Mon, 2016-09-19 16:30

Last question (sorry) - what runs first, the global search+replace regexp or the product mapping regexp?

Many thanks
Jamie

Submitted by support on Mon, 2016-09-19 16:55

Hi Jamie,

Filters first, then the mappings - there is a flow-diagram of the data processing sequence here...

Cheers,
David.
--
PriceTapestry.com