Ara,

> notsmall = '^[^s]*$|^[^s]*(?:s(?!mall)[^s]*)+$'

    This caught my eye as being a little redundant.  To illustrate, if we
let X = '[^s]*' and Y = '(?:s(?!mall)[^s]*)', this can be rewritten as:

        notsmall = "^#{X}$|^#{X}#{Y}+$"

    Which makes it a little easier to see that this is the same as:

        notsmall = "^#{X}#{Y}*$"

    Undoing the substitutions:

        notsmall = '^[^s]*(?:s(?!mall)[^s]*)*$'

    However, making a distinction between the 's' and the 'mall' still
bothered me.  At first I tried simply:

        notsmall = '^(?!small)*$'

    Unfortunately, this only matches a zero length string since the (?!re)
syntax does not consume any characters.  So, I added a '.' to consume the
current character:

        notsmall = '^(?:(?!small).)*$'

    I believe this behaves the same as your original regular expression, but
(IMHO) is much clearer.  However, I have no idea what the performance
implications are.

    I hope someone finds this interesting...

    - Warren Brown