Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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?

share|improve this question
3  
Why not just negate your pattern in Select with !(PATTERN)? –  gpap Sep 17 '13 at 15:15
2  
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
add comment

2 Answers

up vote 6 down vote accepted
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.

share|improve this answer
add comment

Using Pick:

Pick[
  inputset,
  StringMatchQ[inputset, (x_ ~~ __ ~~ x_) | (___ ~~ y_ ~~ y_ ~~ ___)],
  False];
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.