diff --git a/cockatrice/resources/help/search.md b/cockatrice/resources/help/search.md index 917f9482e..7d707b0d1 100644 --- a/cockatrice/resources/help/search.md +++ b/cockatrice/resources/help/search.md @@ -58,4 +58,9 @@ In this list of examples below, each entry has an explanation and can be clicked
Grouping:
t:angel -(angel or c:w) (Any angel that doesn't have angel in its name and isn't white)
+
Regular Expression:
+
[/^fell/](#/^fell/) (Any card name that begins with "fell")
+
[o:/counter target .* spell/](#o:/counter target .* spell/) (Any card text with "counter target *something* spell")
+
[o:/for each .* and\/or .*/](#o:/for each .* and\/or .*/) (/'s can be escaped with a \)
+ diff --git a/cockatrice/src/game/filters/filter_string.cpp b/cockatrice/src/game/filters/filter_string.cpp index e99805541..f5e9d69e9 100644 --- a/cockatrice/src/game/filters/filter_string.cpp +++ b/cockatrice/src/game/filters/filter_string.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -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+ / ["] StringMatcher { + search["NormalMatcher"] = [](const peg::SemanticValues &sv) -> StringMatcher { auto target = std::any_cast(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(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 {