func NewMatchProcessor(pattern string) ProcessorFunc {
	r, err := regexp.Compile(pattern)
	if err != nil {
		return errorProcessorFunc(err)
	}
	return func(in string) (string, bool) {
		return in, r.MatchString(in)
	}
}
NewMatchProcessor returns a processor evaluating the input
against a given pattern and returns the input and true
when it is matching.
package stringex
import (
	"fmt"
	"regexp"
	"strings"
)
type Processor interface {
	Process(in string) (string, bool)
}
type ProcessorFunc func(in string) (string, bool)
func (pf ProcessorFunc) Process(in string) (string, bool) {
	return pf(in)
}
func WrapProcessorFunc(f func(fin string) string) ProcessorFunc {
	return func(in string) (string, bool) {
		return f(in), true
	}
}
func errorProcessorFunc(err error) ProcessorFunc {
	return func(in string) (string, bool) {
		return fmt.Sprintf("error processing '%s': %v", in, err), false
	}
}
func NewChainProcessor(processors ...Processor) ProcessorFunc {
	return func(in string) (string, bool) {
		out := in
		ok := true
		for _, processor := range processors {
			out, ok = processor.Process(out)
			if !ok {
				return "", false
			}
		}
		return out, ok
	}
}
func NewConditionProcessor(decider, affirmer, negater Processor) ProcessorFunc {
	return func(in string) (string, bool) {
		temp, ok := decider.Process(in)
		if ok {
			return affirmer.Process(temp)
		}
		return negater.Process(temp)
	}
}
func NewLoopProcessor(processor Processor) ProcessorFunc {
	return func(in string) (string, bool) {
		temp, ok := processor.Process(in)
		for ok {
			temp, ok = processor.Process(temp)
		}
		return temp, true
	}
}
func NewSplitMapProcessor(sep string, mapper Processor) ProcessorFunc {
	return func(in string) (string, bool) {
		parts := strings.Split(in, sep)
		out := []string{}
		for _, part := range parts {
			if mp, ok := mapper.Process(part); ok {
				out = append(out, mp)
			}
		}
		return strings.Join(out, sep), true
	}
}
func NewSubstringProcessor(index, length int) ProcessorFunc {
	return func(in string) (string, bool) {
		if length < 1 {
			return "", false
		}
		if index < 0 {
			index = 0
		}
		if index >= len(in) {
			return "", true
		}
		out := in[index:]
		if length > len(out) {
			length = len(out)
		}
		return out[:length], true
	}
}