5

I have a function f and its downvalues. I want to code an extra downvalue for arguments of the form "part1:part2"

I don't understand why

f[a__~~":"~~b__] := {a,b}

does not work. I can only think of

f[string_String] /; StringMatchQ[string,__~~":"~~__] := StringCases[string, a__~~":"~~b__ :> {a,b}][[1]]

but this doesn't seem very smart as the string structure is examined two times.

mete
  • 1,188
  • 5
  • 16

1 Answers1

6

It doesn't work because it's simply not correct syntax. String patterns and expression patterns are not interchangeable. Each works only with its own set of functions: string patterns work only in StringMatchQ and expression patterns only work in MatchQ.

In function definitions you can only use expression patterns.

You can use something like this instead:

f[string_String] := 
 Module[{r}, r = StringCases[string, a__ ~~ ":" ~~ b__ :> {a, b}]; First[r] /; r =!= {}]

This special use of Condition inside Module makes it possible not to process the string twice yet still have a condition attached to the definition.

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263
  • Ok, makes sense. I thought (hoped?) that you could throw anything into function definition – mete Feb 17 '14 at 23:28
  • @user2397318 Yes, you can use anything. Your definition is valid, it just doesn't have the meaning you expected. It will match f[x ~~ ":" ~~ y], which as acl said is the same as f[StringExpression[x, ":", y]]. – Szabolcs Feb 17 '14 at 23:30