Avoid unintentional matching of subwords in notifications#820
Avoid unintentional matching of subwords in notifications#820mherger merged 3 commits intoLMS-Community:public/8.4from
Conversation
Use \b to bracket words when creating regular expressions to avoid words matching subwords (eg "play" matching "playlist" and "display"). Fixes LMS-Community#622.
Slim/Control/Request.pm
Outdated
|
|
||
| my @namelist; | ||
| push @namelist, '\b' . $_ . '\b' for (@$names); | ||
| $regexp .= '(?:' . join('|', @namelist) . ')'; |
There was a problem hiding this comment.
Thanks for this PR!
Could this be
$regexp .= '(?:' . join('|', map { "\b$_\b" } @$names) . ')';?
There was a problem hiding this comment.
map is great. If that's worse than you, I can live with it 😄.
There was a problem hiding this comment.
Nothing against map or your one-liner. It was making me smile because you rightfully often pointed out some of Perl code where I condense things way too much and I found this one was not bad 😄
6a78514 to
bc6b853
Compare
Use map { } to simplify construction of the regular expression
for each subword.
Fixes LMS-Community#622.
|
Here are the test outcomes after refactoring a little more aggressively, and using the The test exercises a couple of key test cases: |
michaelherger
left a comment
There was a problem hiding this comment.
Thanks for your effort! You could actually add the test script you created as a real test to the t/ subfolder 😉. Would be the first real unit test in LMS' long history!
Slim/Control/Request.pm
Outdated
| push @regexp, | ||
| '(?:' . join('|', map { "\\b$_\\b" } @$names) . ')' | ||
| if scalar @$names; |
There was a problem hiding this comment.
If an if becomes multi-line I prefer to have it wrapping the conditional statement. Could you please change this?
Is the double backslash in "\\b" required?
There was a problem hiding this comment.
TL;DR "\b" is interpreted as a backspace (BS) whereas "\\b" eq '\b' and "\\b" eq '\\b'.
$pattern1 = '\\bbear';
$pattern2 = '\bbear';
$pattern3 = "\\bbear";
$pattern4 = "\bbear";
die unless
$pattern1 eq $pattern2 &&
$pattern1 eq $pattern3 &&
$pattern1 ne $pattern4;;
print ' ' . ord($_) . ' ' . $_ for split(//, $pattern1);
print "\n";
print ' ' . ord($_) . ' ' . $_ for split(//, $pattern4);
print "\n";
$re1 = qr /$pattern1/;
$re4 = qr /$pattern4/;
$candidate = "black-bear";
die unless $candidate =~ $re1;
die if $candidate =~ $re4;
Slim/Control/Request.pm
Outdated
| } | ||
|
|
||
| return qr /$regexp/; | ||
| return qr /${\(join(',', @regexp))}/; |
There was a problem hiding this comment.
Please, just for readability, as regexes can be confusing enough themselves: could you store the result of the join in a variable $regexp and return as before?
Change layout of multiline conditional. Fixes LMS-Community#622.
|
Thanks! I merged to 8.4 for now. Should be easy to backport should there be a good need. |
Use \b to bracket words when creating regular expressions to avoid words matching subwords (eg "play" matching "playlist" and "display").
Fixes #622.