5
$\begingroup$

May be that I did not understand something about Mathematica pattern matching, but I noticed what follow:

st is a string, inside the string there is a date (Italian format) so I picked this code to extract the date:

st = "aaa ddd f f 20/06/2018 ppp mm l l ooo";

pattern = {"Day", "/", "Month", "/", "Year"};

dateTime = StringCases[st, ___ ~~ x : DatePattern[pattern] ~~ ___ :> x]
{"20/06/2018"}

Every seems to work, but if the day is 21 or 22 or 23 the command gives a wrong day:

someStringDate = {"01/06/2018", "02/06/2018", "10/06/2018", "11/06/2018", "12/06/2018", 
                  "20/06/2018", "21/06/2018", "22/06/2018", "30/06/2018", "31/06/2018"};

pattern = {"Day", "/", "Month", "/", "Year"};

dateTime = 
 StringCases[
  someStringDate, ___ ~~ x : DatePattern[pattern] ~~ ___ :> x]
{{"1/06/2018"}, {"2/06/2018"}, {"10/06/2018"}, 
{"1/06/2018"}, {"2/06/2018"}, {"20/06/2018"}, {"1/06/2018"}, 
{"2/06/2018"}, {"30/06/2018"}, {"1/06/2018"}}

Have you noticed what happens? Does it happen to you too?

PS: I forgot to add the version info

$Version
"11.3.0 for Microsoft Windows (64-bit) (March 7, 2018)"
$\endgroup$
6
$\begingroup$

Use Shortest to find the match where DatePattern is longest:

StringCases[
    someStringDate,
    Shortest[___] ~~ DatePattern[pattern] ~~ ___
]

{{"01/06/2018"}, {"02/06/2018"}, {"10/06/2018"}, {"11/06/2018"}, {"12/06/2018"}, {"20/06/2018"}, {"21/06/2018"}, {"22/06/2018"}, {"30/06/2018"}, {"31/06/2018"}}

$\endgroup$
  • $\begingroup$ Ok, it works. Thanks very much. $\endgroup$ – msalese May 28 '18 at 15:18
  • $\begingroup$ I'd add that if the date pattern is inside a string , above code not work. try to apply the solution to string = "Option FTSE MIB 1st Friday W 15/06/2018 CALL 21700" , not extract the date. $\endgroup$ – msalese May 28 '18 at 16:20
2
$\begingroup$

Since the format of the date is explicitly known, you could construct your own DatePattern:

dp = DigitCharacter ~~ DigitCharacter;
myDatePattern = dp ~~ "/" ~~ dp ~~ "/" ~~ dp ~~ dp;

someStringDate = {"01/06/2018", "02/06/2018", "10/06/2018", 
   "11/06/2018", "12/06/2018", "20/06/2018", "21/06/2018", 
   "22/06/2018", "30/06/2018", "31/06/2018", 
   "Option FTSE MIB 1st Friday W 15/06/2018 CALL 21700", 
   "aaa ddd f f 20/06/2018 ppp mm l l ooo"};

StringCases[someStringDate, myDatePattern]
{{"01/06/2018"}, {"02/06/2018"}, {"10/06/2018"}, {"11/06/2018"}, 
{"12/06/2018"}, {"20/06/2018"}, {"21/06/2018"}, {"22/06/2018"}, 
{"30/06/2018"}, {"31/06/2018"}, {"15/06/2018"}, {"20/06/2018"}}

For higher performance you could use RegularExpression:

myDatePattern2 = RegularExpression["\\d{2}/\\d{2}/\\d{4}"];
StringCases[someStringDate, myDatePattern2]
{{"01/06/2018"}, {"02/06/2018"}, {"10/06/2018"}, {"11/06/2018"}, 
{"12/06/2018"}, {"20/06/2018"}, {"21/06/2018"}, {"22/06/2018"}, 
{"30/06/2018"}, {"31/06/2018"}, {"15/06/2018"}, {"20/06/2018"}}

Note that without the redundant BlankNullSequences everything works with DatePattern by default:

pattern = {"Day", "/", "Month", "/", "Year"};
StringCases[someStringDate, DatePattern[pattern]]
{{"01/06/2018"}, {"02/06/2018"}, {"10/06/2018"}, {"11/06/2018"}, 
{"12/06/2018"}, {"20/06/2018"}, {"21/06/2018"}, {"22/06/2018"}, 
{"30/06/2018"}, {"31/06/2018"}, {"15/06/2018"}, {"20/06/2018"}}
$\endgroup$
  • $\begingroup$ Thanks very much, I've implemented the Alexey Popkov hint , and I found that the slowdown is not due to regularExp rather than the ExceLink component when writing to excel. $\endgroup$ – msalese May 29 '18 at 12:44
1
$\begingroup$

To adapt the code to the situation in which string is like that

string = "Option FTSE MIB 1st Friday W 15/06/2018 CALL 21700"

I modified the command (as suggested by Carl Woll) in this way:

dateTime = StringCases[string,Shortest[___] ~~ x : DatePattern[pattern] ~~ ___ :> x]

It works but is very slow when applied on a long string-list.

$\endgroup$

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.