You could combine all the tests into one regular expression, but I don't recommend it. The following is equivalent to what you wrote:
do_stuff if @string =~ /(?'i'<ingr?>).*(?'a'<prod:alchemy?>)|\g<a>.*\g<i>|<key?>/i
Your regular expressions are a bit odd, so I suspect that what you wrote is not what you meant to write.
The non-capturing grouping parentheses
(?:…) don't seem to serve any purpose, so you can get rid of them.
The other question marks make the preceding letter optional. For example,
<ke> but not
The tricky obstacle to merging the regular expressions is that the
<prod:alchemy?> tests both have to pass, and they can occur in either order. Therefore, you have to allow
<ingr?>.*<prod:alchemy?> as well as
<prod:alchemy?>.*<ingr?> That's possible with
Of course, repeating yourself is bad for verbosity and maintainability. You can lessen the pain slightly by using named groups and subexpression calls.
After having done all that, though, the one long regex is more difficult to understand than your original code. Therefore, I recommend leaving it alone.
If you're dissatisfied with the original code, though, there may be other improvements that you could make, but you haven't provided any context for your question so I can't make alternative suggestions.