Tools
Regular Expressions: Powerful Card Searching
It’s a delightful, but also a daunting challenge to search all 20,000+ cards for effects that make sense in your cube or deck. Lucky for us we have the incredible search tool Scryfall to help us plumb the arcane depths of Magic history.
Existing cube and deck lists are an invaluable resource when designing your own, but can’t cover all of what Magic has to offer. You might know a lot of counterspells but what if you want to consider the complete set of options? A simple search can put every counter spell printed at our fingertips.
Or maybe not quite. Searching for the exact oracle text of “counter target spell” fails to find all the cards that target a specific kind of spell.
Fortunately Scryfall offers us the ultimate tool! Regular Expressions!
Regular Expressions are a powerful search tool used in a computing and text analysis, and perfect for searching Magic cards. In addition to searching for exact text matches, regular expressions offer tools for more sophisticated searches including leaving “blanks” where any text can appear or when text isn’t followed by other term.
Even experienced computer programmers can be intimidated by “Regexes”. They can be very complex, but the simplest tools will get you most of the value. I don’t want to perpetuate the myth that they are dark magic, but they do make you feel a bit like a wizard.
To unlock these search tools on Scryfall, replace the quotes with slashes around your search terms. Instead of o:"counter target spell"
, enter o:/counter target spell/
. Easy.
If you try the two above searches you’ll get the exact same results. Letter and number characters are not treated any differently. Switching our search to regex doesn’t take anything away. Simple text will work as you expect, but we’ve unlocked more tools.
Special characters like .
, \
, /
, *
, {
, }
, (
, )
, -
, ^
, and $
have new meanings that let us craft nuanced searches.
The most common tool is a wildcard. Wildcards ‘match’ any arbitrary text:
If you’re looking for effects that have a regular structure, but might have intervening terms or conditions, inserting a wildcard will broaden your search.
This search wont only return cards with the exact text “counter target spell ”, but also cards that include other text in place of the wildcard, like “creature”, “noncreature”, or “blue”.
You can read it like: find all cards that include the text “counter target ”, followed by any text, followed by “spell”. If you run the search, you’ll see Counterspell is still in our results. .*
is just as happy with no text as anything else.
A common pattern in Magic is “blink” or “flicker” effects which exile a permanent and then return it to the battlefield. We can easily find all cards which use these two key words.
This gets us pretty far, but also finds more cards that use these words in different contexts that don’t apply to what we’re looking for, or uses them in two separate abilities. We can be more clear about what we’re looking for with a wildcard.
This ensures both that the words are in the right order and in a single ability, cutting the results in half and getting us much closer to the cards we’re actually looking for.
Using .*
together is so ubiquitous it’s almost synonymous with “regular expression”. On its own, a period means “any character”. An asterisk means “any number of the previous thing”. Together they search for any amount of anything.
If we want to be really nitpicky, a period allows anything except a line break, so one.*two
will find cards with “one” and “two” in a single ability. For the most part this is what we want since the order of abilities is usually not mechanically meaningful.
Wildcards are useful for finding cards with specific costs and effects.
This search finds cards that include sacrificing something and drawing a card. You’ll also find it still returns many cards you’re not interested in.
Adding the colon ensures “sacrifice” is actually part of the cost of an activated ability. The colon isn’t any fancy regex syntax, it’s just how activated abilities are worded. Another wildcard allows other parts to the cost.
Multiple words often have similar functions. If we’re looking removal spells we might not care if it destroys or exiles its target. We can allow either by wrapping all options in parentheses and separating them with pipes.
We can include any number of options. This is similar to a wildcard in that our search can find cards with multiple options, but we can be more specific.
^
represents the beginning and end of a line of text. This is particularly useful if we want to be sure an effect starts with a particular cost and no other.
This search returns all cards with an effect that costs only sacrificing a creature with no other cost. ^
ensures this is the beginning of an effect and no cost comes before.
The end of a line is represented by $
.
Using the two together, this query finds all the commander creatures with the ‘partner’ ability, excluding creatures that have a specific “partner with…“.
You may have noticed a problem. What happens if the text we’re searching for includes some of the special regular expression characters? This will come up a lot when searching for cards with symbols, which are written with curly braces in the Oracle text. {t}
represents the tap symbol, {r}
red mana, and {1}
generic mana. o:/^{1}:/
wont do what we want because the braces are assumed to mean something else. To fix this, precede any special characters you want to be treated as-is with a slash \
to “escape” them.
This search gives us all cards with effects that cost exactly one generic mana, and no other cost.
What happens if you need an actual slash? Escape it with a slash! How far does this go? It’s slashes all the way down.
I’ll admit, this is starting to look pretty wild. If you’re not sure if you need to ‘escape’ a certain character just try the simple thing first and add slashes if it doesn’t work. You’re free to experiment. You won’t break anything.
Some letters preceded by a \
unlock a new tool. \d
means a number character. We could use it to find all cards that deal any amount of damage.
That’s a lot of damage. Shouldn’t Aetherflux Reservoir be here though? This expression doesn’t mean “deals any number damage” in the sense that a normal human would understand it. \d
means specifically one digit, 0 through 9. It’s the same thing as (0|1|2|3|4|5|6|7|8|9)
.
Adding a plus sign fixes this. +
allows one or more of the previous thing. It’s the same as *
but there must be at least one where an asterisk allows nothing.
Numbers come up a when modifying power and toughness.
It takes a lot of slashes to escape the literal plus signs and slashes that appear in the card text, but this finds all effects that increase power and toughness.
Occasionally a particular word will also be a fragment of a longer word. A search for artifact
will give you cards referencing nonartifact
. Literally the opposite of what you want.
Specify something isn’t part of a longer word with “word boundaries”, represented by \b
. This doesn’t match a specific character but the end or beginning of a word: where a letter character is adjacent to a space, punctuation, or the beginning or end of a line.
This gives us all cards referencing “artifact” excluding “nonartifact”. Note we didn’t add a \b
at the end, so it will also match “artifacts“.
Without regular expressions, we might try to solve this by explicitly excluding “nonartifact” with o:artifact -o:nonartifact
. This almost works but will exclude cards that reference both “artifact” and “nonartifact” which we might actually care about.
Some cases can’t be solved by a word boundary, but we can explicitly search for text that isn’t preceded by some other with “negative lookarounds”. Wrap the text you don’t want in (?<!text)
or (?!text)
. Replacing “text” with the word you don’t want to be present.
We can fix our ‘nonartifact’ issue more explicitly with a negative lookbehind, specifically excluding cards that include “artifact” directly preceded by “non”.
This does the same thing looking forward finding effects that exile, but do not “return”. Notice we’ve had to throw our good old wildcard .*
in there too. Because the lookahead checks the adjacent text we need to say there could be more text between “creature” and “return”.
What’s with this weird syntax? Why (?<!)
? Truthfully, no reason. A programmer decades ago had to choose something, and that’s what made sense to them. Don’t try to memorize the syntax. Get a sense of what’s possible. When you need a specific tool, look it up, or search the web describing what you want to do.
As valuable as these tools are in isolation, they’re even more so in combination.
We can combine our search for cards that destroy or exile a creature with a wildcard to allow intervening conditions to return even more removal spells.
And, we can combine these regular expression searches of the full card text with other card attributes, like restricting our search to just instants that I can play in my blue-red commander deck.
If you’re not sure where to start check out the examples below for one you can use as a template.
If you’re writing your own, there’s a simple strategy. Start simple, even with just a plain-text search, and iterate. You can try adding some wildcards to broaden your search if you think things are missed. Use other tools to exclude false matches. As you get more comfortable writing searches you’ll be able to iterate to a practical list of results you can search through more and more quickly.
Critically, be aware the text of Magic cards follows specific patterns and use a specific set of terms. The consistent templating makes using regular expressions very effective. Since the same effects are worded in the same way it’s possible to write regular expression ‘patterns’ that express that templating.
Keep in mind universal structures like a colon in activated abilities, and “whenever” or “at” in triggered abilities, the way symbols are written in the oracle text, and that ”~” can be used to reference a card’s name.
Wizards of the Coast has even done us a huge favor updating the “oracle text” of old cards to match the current standards making our searches effective across Magic history.
For many situations there won’t be a practical search that will find 100% of the cards that that might be relevant to you, or exclude all that don’t. Magic cards are written in a very consistent way, but there are a huge variety of effects. Sometimes the same result is accomplished in different ways. Your powerful new search for all counter spells still might miss a few that take an entirely different approach.
This is a powerful tool, but just one. The perfect regex search can’t completely replace broad keyword searches and a lot of time, our communal knowledge, or just taking the time to explore your collection.
Regular expressions been used for decades in computer programming. They are a powerful search tool, and also can be used to analyze, validate, and even transform text. If you find them useful, keep an eye out. You might find other places they can be used.