Support regex in card search (#5971)

This commit is contained in:
RickyRister
2025-06-12 16:30:43 -07:00
committed by GitHub
parent e7a6126fbd
commit 456da93465
2 changed files with 31 additions and 11 deletions

View File

@@ -58,4 +58,9 @@ In this list of examples below, each entry has an explanation and can be clicked
<dt>Grouping:</dt>
<dd><a href="#t:angel -(angel or c:w)">t:angel -(angel or c:w)</a> <small>(Any angel that doesn't have angel in its name and isn't white)</small></dd>
<dt>Regular Expression:</dt>
<dd>[/^fell/](#/^fell/) <small>(Any card name that begins with "fell")</small></dd>
<dd>[o:/counter target .* spell/](#o:/counter target .* spell/) <small>(Any card text with "counter target *something* spell")</small></dd>
<dd>[o:/for each .* and\/or .*/](#o:/for each .* and\/or .*/) <small>(/'s can be escaped with a \)</small></dd>
</dl>

View File

@@ -4,6 +4,7 @@
#include <QByteArray>
#include <QDebug>
#include <QRegularExpression>
#include <QString>
#include <functional>
@@ -20,7 +21,7 @@ QueryPart <- NotQuery / SetQuery / RarityQuery / CMCQuery / FormatQuery / PowerQ
NotQuery <- ('NOT' ws/'-') SomewhatComplexQueryPart
SetQuery <- ('e'/'set') [:] FlexStringValue
OracleQuery <- 'o' [:] RegexString
OracleQuery <- 'o' [:] MatcherString
CMCQuery <- ('cmc'/'mv') ws? NumericExpression
@@ -42,7 +43,7 @@ ColorEx <- Color / [mc]
ColorQuery <- [cC] 'olor'? <[iI]?> <[:!]> ColorEx*
FieldQuery <- String [:] RegexString / String ws? NumericExpression
FieldQuery <- String [:] MatcherString / String ws? NumericExpression
NonDoubleQuoteUnlessEscaped <- '\\\"'. / !["].
NonSingleQuoteUnlessEscaped <- "\\\'". / !['].
@@ -52,8 +53,14 @@ String <- SingleApostropheString / UnescapedStringListPart+ / ["] <NonDoubleQuot
StringValue <- String / [(] StringList [)]
StringList <- StringListString (ws? [,] ws? StringListString)*
StringListString <- UnescapedStringListPart+
GenericQuery <- RegexString
RegexString <- String
GenericQuery <- MatcherString
# A String that can either be a normal string or a regex search string
MatcherString <- RegexMatcher / NormalMatcher
NormalMatcher <- String
RegexMatcher <- '/' RegexMatcherString '/'
RegexMatcherString <- ('\\/' / !'/' .)+
FlexStringValue <- CompactStringSet / String / [(] StringList [)]
CompactStringSet <- StringListString ([,+] StringListString)+
@@ -261,14 +268,22 @@ static void setupParserRules()
return QString::fromStdString(std::string(sv.sv()));
};
search["RegexString"] = [](const peg::SemanticValues &sv) -> StringMatcher {
search["NormalMatcher"] = [](const peg::SemanticValues &sv) -> StringMatcher {
auto target = std::any_cast<QString>(sv[0]);
return [=](const QString &s) {
auto sanitizedTarget = QString(target);
sanitizedTarget.replace("\\\"", "\"");
sanitizedTarget.replace("\\'", "'");
return s.contains(sanitizedTarget, Qt::CaseInsensitive);
};
auto sanitizedTarget = QString(target);
sanitizedTarget.replace("\\\"", "\"");
sanitizedTarget.replace("\\'", "'");
return [=](const QString &s) { return s.contains(sanitizedTarget, Qt::CaseInsensitive); };
};
search["RegexMatcher"] = [](const peg::SemanticValues &sv) -> StringMatcher {
auto target = std::any_cast<QString>(sv[0]);
auto regex = QRegularExpression(target, QRegularExpression::CaseInsensitiveOption);
return [=](const QString &s) { return regex.match(s).hasMatch(); };
};
search["RegexMatcherString"] = [](const peg::SemanticValues &sv) -> QString {
return QString::fromStdString(sv.token_to_string());
};
search["OracleQuery"] = [](const peg::SemanticValues &sv) -> Filter {