I don't see a problem with that.

Can it not be seen as a mere implementation detail?

You can have your StringValidator constructor overloads dispatch their argument to various protected properties:

    public class StringValidator
    {
        protected void Require(object pattern)
        {
            if (pattern == null)
            {
                throw new ArgumentNullException("pattern", "cannot be null");
            }
        }

        public StringValidator(Regex pattern)
        {
            Require(pattern);
            RegexValidation = pattern;
        }

        public StringValidator(string pattern)
        {
            Require(pattern);
            WildcardValidation = pattern;
        }

        // Derived validators, if any, will just override this, by:
        // if (NewValidation != null) {
        // ...
        // }
        // else
        //     return base.Validate(input);
        protected virtual bool Validate(string input)
        {
            if (WildcardValidation != null)
            { // Wildcard matching strategy
              // return ...
            }
            else
            { // Regex matching strategy
              // return ...
            }
            // Proper constructors will guarantee there is exactly one validation implementation
        }

        protected string WildcardValidation { get; private set; }

        protected Regex RegexValidation { get; private set; }
        
        // Etc
    }

'Hope this helps.