34
$\begingroup$

What are, and how do I use Mathematica's string matching and replacement tools?

$\endgroup$

2 Answers 2

31
$\begingroup$

There are three different mechanisms provided for matching string patterns in Mathematica. Each of these must be used within functions that are equipped to handle strings. You cannot, for instance, use:

{"abc", "def", "ghi"} /. "a*" -> 1
Replace["downwind", "downw" -> "resc"]

to any effect. Instead you would use:

{"abc", "def", "ghi"} /. x_String /; StringMatchQ[x, "a*"] -> 1
StringReplace["downwind", "downw" -> "resc"]

Simple wildcard matching:

Mathematica graphics

Example: StringMatchQ["abcde", "ab*"] yields True.

Wildcards (or "metacharacters") do not work natively in functions such as StringReplace and StringCases and are usually used with StringMatchQ. They also work with and are useful for simple commands such as Names["Pre*"].

Regular Expressions

Since version 5.1 Mathematica supports regular expressions. I am not an expert on regular expression use, and detailed usage information is readily available in both the Mathematica documentation and elsewhere, so I leave it to the reader to explore. RegEx is powerful and popular with those doing a lot of string manipulation, especially for performance.

StringExpression

Also since version 5.1 there is a paradigm of using familiar Mathematica expression patterns for strings, along with a multitude of special named patterns, within a StringExpression object. It has the short infix form ~~ such thata ~~ b ~~ c has the long form StringExpression[a, b, c].

StringExpression also accepts patterns in the RegularExpression form making it the master method for Mathematica string patterns.

A major advantage of this new paradigm is that you can use most of the Mathematica pattern elements you should already be familiar with, such as _, __, ___, .., ..., Except, Shortest, Longest etc. You can also name these patterns as you can in expression matching.

Here is a contrived replacement on the start of Lorem ipsum using Blank, Repeated, Condition, and Pattern:

sample = StringTake[ExampleData[{"Text", "LoremIpsum"}], 200];

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer nunc augue, feugiat non, egestas ut, rutrum eu, purus. Vestibulum condimentum commodo pede. Nam in metus eu justo commodo posuere. Nun

StringReplace[
  sample,
  x_ ~~ y : Repeated[LetterCharacter, 5] ~~ " " /; UpperCaseQ[x] :> "X" <> y <> " "
]

Xorem ipsum dolor sit amet, consectetuer adipiscing elit. Integer nunc augue, feugiat non, egestas ut, rutrum eu, purus. Vestibulum condimentum commodo pede. Xam in metus eu justo commodo posuere. Nun

$\endgroup$
10
  • 3
    $\begingroup$ +1. I think it would be good to mention that patterns are intrinsically more powerful than regexps, since you can construct recursive patterns, so that you can do with patterns things not possible with reg.exps, but this flexibility comes at a price of performance, and performance hit is very substantial, so that one of the most common performance-tuning tricks for string matching is to rewrite patterns using reg.exps. $\endgroup$ Jun 18, 2012 at 20:10
  • $\begingroup$ Perhaps three nice goodies could be mentioned in your answer: Shortest, Longest and Except $\endgroup$ Jun 18, 2012 at 20:13
  • $\begingroup$ @Leonid thanks, I'll get on it. $\endgroup$
    – Mr.Wizard
    Jun 18, 2012 at 20:16
  • 3
    $\begingroup$ @Leonid For examples of string patterns that cannot be implemented (solely) as regex, see the "implementation" section of Working with String Patterns $\endgroup$
    – WReach
    Jun 18, 2012 at 22:00
  • 4
    $\begingroup$ @WReach Ok, thanks! This is good to know. I always suspected that there is a conversion to reg.exps, and even wanted to write a converter myself as an excercise. It is good to know that this exists. On a different matter, I think I start to understand how to prompt you to appear (for the benefits of all of us), although this time I did not do it on purpose :). Seriously, I miss you answers these days, and I am sure I am not alone. $\endgroup$ Jun 18, 2012 at 22:15
16
$\begingroup$

Mr.Wizard's answer is of course a nice overview. But one can also answer this question by pointing to the documentation - and I don't mean this as a drive-by answer, but as an actually worth-while activity:

For a nice coherent exposition of all the string matching functionality, do the following:

  • open the Documentation Center
  • Click on the Book icon at the top:

book

Navigate through the sections indicated in this screenshot:

index

It is a well-written overview, I think.

$\endgroup$

Your Answer

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

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