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 Answers 2

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$
16
  • $\begingroup$ @garej no because there the _ is repeated exactly twice. $\endgroup$
    – Kuba
    Commented Feb 23, 2016 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
    Commented Feb 23, 2016 at 10:00
  • $\begingroup$ @User18 take a look at the last on I've just edited. $\endgroup$
    – Kuba
    Commented Feb 23, 2016 at 10:01
  • $\begingroup$ @Kuba, I see, by the way, how to avoid ToExpression to round up the string number? $\endgroup$
    – garej
    Commented Feb 23, 2016 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
    Commented Feb 23, 2016 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$
9
  • $\begingroup$ @Kuba, see the edit $\endgroup$
    – Jason B.
    Commented Feb 23, 2016 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
    Commented Feb 23, 2016 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.
    Commented Feb 23, 2016 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
    Commented Feb 23, 2016 at 11:03
  • $\begingroup$ That's probably not a real life example but still: MatchQ[RotateLeft @@ (RealDigits[22.1111111111111111]), {_, 1 .., 2, __}] $\endgroup$
    – Kuba
    Commented Feb 23, 2016 at 11:10

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.