5

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?

Vajira
  • 601
  • 5
  • 13
  • 3
    Why not just negate your pattern in Select with !(PATTERN)? – gpap Sep 17 '13 at 15:15
  • 3
    Did you take a look at Except? – Jacob Akkerboom Sep 17 '13 at 15:17
  • 2
    @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

2 Answers2

6
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.

Dr. belisarius
  • 115,881
  • 13
  • 203
  • 453
5

Using Pick:

Pick[
  inputset,
  StringMatchQ[inputset, (x_ ~~ __ ~~ x_) | (___ ~~ y_ ~~ y_ ~~ ___)],
  False];
ssch
  • 16,590
  • 2
  • 53
  • 88