14

I am trying to get Position work with patterns. I have the following code:

dat = {"star", "u", "g", "r", "i", "z", "star2", "u", "g", "r", "i", 
   "z", "star3", "u", "g", "r", "i", "z", "star4", "u", "g", "r", "i",
    "z", "Astro", "u", "g", "r", "i", "z"};
Position[dat, "star" ~~ _]
Position[dat, RegularExpression["star."]]

Netheir returns anything. What I want is to return position of "star", "star2" etc. How do I properly use patterns with Position?

atapaka
  • 3,954
  • 13
  • 33
  • @kglr No, this does not return the first one. Also it returns empty fields of dimensions of the original list. I would prefer make it work in the way Position works and also understand why this does not actually work – atapaka Jun 13 '16 at 22:01
  • 2
    As to the "why?"... Patterns and string patterns are two distinct syntactic forms. Position only supports the former. The reasons for the distinction are discussed in (8945). – WReach Jun 14 '16 at 14:20

2 Answers2

14

For large lists, this should be snappy:

Pick[Range@Length@dat, StringTake[dat, UpTo@4], "star"]

and actually, taking advantage of listability,

Pick[Range@Length@dat, StringMatchQ[dat, "star*"]]

is a bit faster it seems...

ciao
  • 25,774
  • 2
  • 58
  • 139
13
Position[dat, _String?(StringMatchQ[#, "star" ~~ ___] &)]

or

Position[dat, _String?(StringMatchQ[#, "star*"] &)]

or

Position[dat, _?(StringMatchQ[#, "star*"] &), Heads -> False]

or

Position[StringMatchQ[dat, "star*"], True] (*thanks: @TomD *)

{{1}, {7}, {13}, {19}}

Alternatively,

Pick[Range@Length@dat, StringMatchQ[#, "star*"] & /@ dat]

{1, 7, 13, 19}

kglr
  • 394,356
  • 18
  • 477
  • 896