# How to get complement of a pattern

I have a list. I want to get all the elements in that list which do not match a given pattern. That is, I want the strings which do not match any of the following patterns:

1. First and last characters are the same: $123aw1$
2. Does not have two consecutive similar characters: $1era22we, awe33rt, 123aa123$

I wrote following code

inputset = ToString /@ {
11223434, 12123434, 11234342, 11234243, 11234234, 11232434, 12132434,
12134234, 11234324, 11232443, 11234423, 12134243, 12314234, 12314324,
12341234, 11223344, 11223443, 11234432
};
outputset = Complement[inputset,
Select[inputset,
StringMatchQ[#, StringExpression[x_, ___, x_]] ||
StringMatchQ[#, StringExpression[___, x_, x_, ___]] &]];


and I got

outputset = {12123434, 12132434, 12134234, 12134243, 12314234, 12314324, 12341234}


Is there an easy simple and efficient way to do this?

-
Why not just negate your pattern in Select with !(PATTERN)? –  gpap Sep 17 '13 at 15:15
Did you take a look at Except? –  Jacob Akkerboom Sep 17 '13 at 15:17
@JacobAkkerboom Except is pretty limited on string patterns, it only works on one character. You can't use it like: StringMatchQ[{"abc","xyz"}, Except["abc"]] –  ssch Sep 17 '13 at 15:32
What is the measure of similarity for "two consecutive similar characters"? –  m_goldberg Sep 17 '13 at 15:49
I mean same character appear at position "i" and position "i+1" of given string. "i" can be any position. So I don't want string like "1123", "23345","145aa". Also I don't want string which has same character at beginning and end like "a12wea", "12w33qw1", "2ert442" –  Vajira Sep 17 '13 at 16:35

Select[inputset, Not@(StringMatchQ[#, x_ ~~ __ ~~ x_] ||
StringMatchQ[#, ___ ~~ y_ ~~ y_ ~~ ___]) &]


I'm always suspicious about the use of Alternatives[] in string patterns, but in this case it seems to work. So you may also write a more compact form:

Select[inputset, ! StringMatchQ[#, (x_ ~~ __ ~~ x_)  | ( ___ ~~ y_ ~~ y_ ~~ ___)] &]


Note the need for parenthesizing.

-

Using Pick:

Pick[
inputset,
StringMatchQ[inputset, (x_ ~~ __ ~~ x_) | (___ ~~ y_ ~~ y_ ~~ ___)],
False];

-