4
$\begingroup$

If I have a list of numbers like this:

list = {0.3565127, 0.8656421, 0.231479879, 0.39698787, 0.536987651},

which are all between 0 and 1, each having lots of digits, and whose precision is not known (and also not important). I don't know their exact values. (It could be a list of hundreds of numbers, so we don't know each of them exactly).

Yet I know some of them have the form 0.?969?????????, where the ?s represent digits I do not know; besides; the digits known are all within the first five digits behind the decimal point.

So, how can I construct a pattern object (like x_^2 for symbols) for replacing numbers that match the pattern?

$\endgroup$
2
$\begingroup$

Inspired by Jason B:

Select[list,
  MatchQ[
    TakeDrop[
      If[Negative[#2], ArrayPad[#1, {Abs[#2], 0}], #1], 
      Clip[#2, {0, \[Infinity]}]
    ] & @@ RealDigits[#] &, 
    {{}, {_, 9, 6, 9, __}}
  ] &
]
{0.396988}

Where the first list in patterns specifies the pattern for digits on the left side of the decimal point and the second for those on the right.

For earlier versions TakeDrop can be replaced with Through[{Take, Drop}[##]] &


Old answer

Not exactly pattern matching, but working:

Select[
 list,
 Mod[Floor[# 10^4], 10^3] == 565 &
]
{0.356513}

Same approach, slightly modified:

Pick[
   list,
   Mod[Floor[list 10^4], 10^3],
   565
]

Probably slower string approach:

StringCases[
  ToString[#, InputForm] & /@ list,
  StartOfString ~~ _ ~~ "." ~~ Repeated[_, {2}] ~~ "65" ~~ __ ~~ EndOfString
] // Flatten // Map[ToExpression]
{0.356513}

or, matching your question the best:

Cases[
    ToString[#, InputForm] & /@ list,
    _?(StringMatchQ[#, RegularExpression[".\\...698.*"]] &)
] // Flatten // Map[ToExpression]
{0.396988, 0.536988}
$\endgroup$
  • $\begingroup$ @garej no because there the _ is repeated exactly twice. $\endgroup$ – Kuba Feb 23 '16 at 9:53
  • $\begingroup$ @Kuba Thank you! Yes it is an equally good alternative. Oh, but is there a convenient method in Mathematica to form a pattern object in such cases? What I have in mind is things like wild cards within the numbers, like this: 0.*565****..., where the * is a wild card. $\endgroup$ – User18 Feb 23 '16 at 10:00
  • $\begingroup$ @User18 take a look at the last on I've just edited. $\endgroup$ – Kuba Feb 23 '16 at 10:01
  • $\begingroup$ @Kuba, I see, by the way, how to avoid ToExpression to round up the string number? $\endgroup$ – garej Feb 23 '16 at 10:03
  • 1
    $\begingroup$ @garej Select and Pick are aiming in ?,?565?... while the last one is looking for ?,??698?.... Where by ?... I mean repeated ? and by , I mean decimal point. $\endgroup$ – Kuba Feb 23 '16 at 10:21
4
$\begingroup$

It seems that OP wants a pattern object for use in replacement rules, so this does the trick,

{0.969, 0.0969, 0.00969, 0.3565127, 0.8656421, 0.231479879, 
  0.39698787, 0.536987651} /. 
 a_ /; MatchQ[
    First[RealDigits[a, 10, Automatic, -1]], {_, 9, 6, 9, __}] -> 4
(* {0.969, 4, 0.00969, 0.356513, 0.865642, 0.23148, 4, 0.536988} *)

edit Thanks as always to @J.M. for helping me write better Mathematica code.

$\endgroup$
  • $\begingroup$ @Kuba, see the edit $\endgroup$ – Jason B. Feb 23 '16 at 10:37
  • $\begingroup$ Thanks ;) p.s. Drop will be safer, and PatternSequence seems to be redundant. MatchQ[ Drop @@ RealDigits[1.096956], {_, 9, 6, 9, __} ] $\endgroup$ – Kuba Feb 23 '16 at 10:45
  • 1
    $\begingroup$ @Kuba, Drop doesn't seem to do the trick all the time either, see Drop @@ RealDigits[0.063548] $\endgroup$ – Jason B. Feb 23 '16 at 10:53
  • $\begingroup$ @JasonB Right, please see my edit. p.s. I always felt like RealDigits output doesn't fit list manipulation practices in MMA. $\endgroup$ – Kuba Feb 23 '16 at 11:03
  • $\begingroup$ That's probably not a real life example but still: MatchQ[RotateLeft @@ (RealDigits[22.1111111111111111]), {_, 1 .., 2, __}] $\endgroup$ – Kuba Feb 23 '16 at 11:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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