1
$\begingroup$

Say I'd like to pick substrings from some string such that these substrings have the pattern @@@q@@@, where @ is used here as a stand-in for a 'wildcard' character (i.e. any character) and q is just an example of a specific character that can be specified as desired.

The kind of lame solution might be as follows:

substringList = StringTake[testString, # + {-3, 3} & /@ StringPosition[testString, "q"]];

This, of course, runs into trouble when q appears near one of the two ends of testString. What's the correct way to do this?

$\endgroup$
11
  • $\begingroup$ Have you seen StringCases? The tutorials at the bottom of the StringCases documentation (specifically, the ones on String Patterns) will also come in useful. $\endgroup$
    – Aky
    Commented Apr 4, 2014 at 17:46
  • $\begingroup$ @Aky I'm actually looking through that now, however it's not clear how to specify wildcard sequences flanking some character of interest? For example, this pattern "a" ~~ x_ ~~ "c" is workable, but how do we ask for something like my example ~~~x~~~~? $\endgroup$
    – CA30
    Commented Apr 4, 2014 at 17:47
  • $\begingroup$ @CA30 ~ joins patterns only. p.s. is each wildcard different? $\endgroup$
    – Kuba
    Commented Apr 4, 2014 at 17:50
  • $\begingroup$ @Kuba Yes, here each 'wildcard' can be different. It just means "I don't care what's here, return it." But it does have to mean that 'some' character is there. We can't run off the ends of the string! $\endgroup$
    – CA30
    Commented Apr 4, 2014 at 17:51
  • 2
    $\begingroup$ Try something like StringCases["acaqaddqccxjq", RegularExpression["...q..."], Overlaps -> True], which returns {"acaqadd", "addqccx"} $\endgroup$
    – Aky
    Commented Apr 4, 2014 at 17:54

1 Answer 1

5
$\begingroup$

Please reference: How do I perform string matching and replacements?

Using StringExpression:

string = ExampleData[{"Text", "DeclarationOfIndependence"}];

StringCases[string, _ ~~ _ ~~ _ ~~ "q" ~~ _ ~~ _ ~~ _]
{"d equal", " requir", "d equal", "linquis", "or quar", " acquie"}

Or:

StringCases[string, # ~~ "q" ~~ #] & @ Repeated[_, {3}]
{"d equal", " requir", "d equal", "linquis", "or quar", " acquie"}

Using RegularExpression as already shown by Aky:

StringCases[string, RegularExpression["...q..."]]
{"d equal", " requir", "d equal", "linquis", "or quar", " acquie"}

Or as I just (re)discovered using StringPattern`PatternConvert as noted in the comments below:

StringCases[string, RegularExpression[".{3}q.{3}"]]
{"d equal", " requir", "d equal", "linquis", "or quar", " acquie"}
$\endgroup$
5
  • $\begingroup$ Wasn't aware that Repeated worked with string patterns too.. +1. $\endgroup$
    – Aky
    Commented Apr 4, 2014 at 20:11
  • 1
    $\begingroup$ @Aky That's the beauty of StringExpression: you can use nearly all of the native Mathematica pattern operators in application to strings. Regular Expressions are often shorter for those well accustomed to them, but since I am not it usually takes me less time to write the StringExpression equivalent. Mathematica actually converts the StringExpression to a Regular Expression before handing off the operation to an optimized string library. You can see what is produced using StringPattern`PatternConvert. For example: (continued) $\endgroup$
    – Mr.Wizard
    Commented Apr 4, 2014 at 20:18
  • 3
    $\begingroup$ First @ StringPattern`PatternConvert[Repeated[_, {3}] ~~ "q" ~~ Repeated[_, {3}]] yields "(?ms).{3}q.{3}". You can use this to learn how to write RegularExpression patterns. (?ms) has to do with multi-line behavior; .{3} is the concise form of Repeated[_, {3}] in RE language. $\endgroup$
    – Mr.Wizard
    Commented Apr 4, 2014 at 20:19
  • $\begingroup$ cool beans! I had no idea about all this. $\endgroup$
    – Aky
    Commented Apr 4, 2014 at 20:22
  • $\begingroup$ @Aky As always, I'm glad I could help. :-) $\endgroup$
    – Mr.Wizard
    Commented Apr 4, 2014 at 20:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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