Textscan won't read the dates with spaces

Textscan doesn't work when date elements are separated by spaces. However the same format works when used with datetime function. Have a look at the following code:
textscan('1959 05 21','%{yyyy MM dd}D') % Doesn't work when there are spaces
datetime('now','Format','yyyy MM dd') % same format works with datetime function
textscan('1959-05-21','%{yyyy-MM-dd}D') % Works when when space is replaced with non letter character
textscan('1959 05 21','%{yyyy MM dd}D','whitespace','') % Works when whitespace is set to none
textscan('1959 05 21 567','%{yyyy MM dd}D%d','whitespace','') % Doesn't work
How can I make last line of the code to work?
Thanks
PS: Read Walter Roberson and per isakson's comments on the accepted answer

1 件のコメント

per isakson
per isakson 2017 年 8 月 15 日
編集済み: per isakson 2017 年 8 月 17 日
"How can I make last line of the code to work?" I don't think it's possible. It seems that Matlab cannot handle the double use of space, as part of the date format and at the same time as list separator before the integer.
I assume that your problem is not to parse the string, but to find the limits of textscan.

サインインしてコメントする。

 採用された回答

Jeremy Hughes
Jeremy Hughes 2017 年 8 月 16 日

1 投票

Hi Per,
The issue is that textscan's delimiter is space by default. Parsing happens first, then datatype conversion. In this case, you're getting
"1959 05 21" -> "1959","05","21"
and trying to convert each of these into it own datetime. This is a pretty common confusion.
The trick to parsing this correctly is to supply 'Delimiter' to textscan. Try:
textscan('1959 05 21','%{yyyy MM dd}D','Delimiter',',')
Hope this helps, Jeremy

2 件のコメント

Walter Roberson
Walter Roberson 2017 年 8 月 16 日
Note that the attempts
textscan('1959 05 21 567','%{yyyy MM dd}D%d','whitespace','')
or
textscan('1959 05 21 567','%{yyyy MM dd}D%d','Delimiter',',')
will not work, and
textscan('1959 05 21 567','%{yyyy MM dd}D%*[ ]%d','whitespace','')
will not work either. In each of those case, the entire group 1959 05 21 567 gets grabbed and passed to datetime for parsing. textscan parsing is greedy that way, just as is the case for numeric fields:
>> textscan('123456', '%d4%d')
ans =
1×2 cell array
{[123456]} {0×1 int32}
>> textscan('123456', '%d%*[4]%d')
ans =
1×2 cell array
{[123456]} {0×1 int32}
>> textscan('123456', '%d%d','delimiter','4')
ans =
1×2 cell array
{[123456]} {0×1 int32}
>> textscan('123e56', '%de%d')
ans =
1×2 cell array
{[2147483647]} {0×1 int32}
>> textscan('123e56', '%d%*[e]%d')
ans =
1×2 cell array
{[2147483647]} {0×1 int32}
>> textscan('123e56', '%d%d','delimiter','e')
ans =
1×2 cell array
{[2147483647]} {0×1 int32}
>> textscan('123e56', '%d%d','whitespace','e')
ans =
1×2 cell array
{[2147483647]} {0×1 int32}
per isakson
per isakson 2017 年 8 月 16 日
編集済み: per isakson 2017 年 8 月 22 日
Had the task been to read and parse the string, '1959 05 21 567', I would have tried
cac = textscan('1959 05 21 567','%10c%d');
dt = datetime( cac{1},'Format','yyyy MM dd');
Note: this doesn't work with (a varying number of) leading spaces.
>> textscan(' 1959 05 21 567','%12c%d')
ans =
'1959 05 21 5' [67]
The Conversion Specifier, %c, lets me decide how many characters to read (except for leading (white)spaces) and these two lines are surprisingly efficient. ( %c is cheap.)
However, with 'whitespace','' it works
>> textscan(' 1959 05 21 567','%12c%d', 'Whitespace','')
ans =
' 1959 05 21' [567]
>> textscan(' 1959 05 21 567 890','%12c%d%d', 'whitespace','')
ans =
' 1959 05 21' [567] [890]

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeCharacters and Strings についてさらに検索

質問済み:

D
D
2017 年 8 月 15 日

編集済み:

D
D
2017 年 8 月 23 日

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by