How do I get regexp to read specific values in a text file?
8 次查看(过去 30 天)
显示 更早的评论
I have a text file containing numerous blocks of data that look like this:
Type: 1 Part ID: 23568 Time Tag: 55012.12345678
Loc ID: 1 Bar ID: 9 Past LR: 0 Isync/Osync: 1
Platform: 1
Type: 1 Part ID: 23568 Time Tag: 55057.12345678
Loc ID: 1 Bar ID: 9 Past LR: 0 Isync/Osync: 1
Platform: 1
Type: 1 Part ID: 23568 Time Tag: 55123.12345678
Loc ID: 1 Bar ID: 6 Past LR: 0 Isync/Osync: 1
Platform: 23
Type: 1 Part ID: 23568 Time Tag: 55124.12345678
Loc ID: 1 Bar ID: 4 Past LR: 0 Isync/Osync: 1
Platform: 23
Type: 1 Part ID: 23568 Time Tag: 55213.12345678
Loc ID: 1 Bar ID: 9 Past LR: 0 Isync/Osync: 1
Platform: 55
Type: 1 Part ID: 23568 Time Tag: 55300.12345678
Loc ID: 1 Bar ID: 11 Past LR: 0 Isync/Osync: 1
Platform: 55
I’m attempting to extract the numeric values for the time tag, Bar ID, and Platform parameters, then store the data separately for plots.
However, I can’t seem to get the proper expression to read the individual values. I’ve tried multiple expressions. The following is the closest I’ve gotten to achieving any values at all:
indata = fileread('data.txt');
pattern = 'Platform:\s\d+';
data = regexp(indata,pattern);
This results in a < 1 x 3 double>
97 207 317
I’ve got to be missing something simple. Any ideas on how to get this to extract the proper values?
2 个评论
Matt Kindig
2013-5-16
编辑:Matt Kindig
2013-5-16
What is the difference between this format:
Platform: 1
Type: 1 Part ID: 23568 Time Tag: 55057.12345678
And this format:
Platform: 1 Type: 1 Part ID: 23568 Time Tag: 55123.12345678
Should both be handled the same?
采纳的回答
Matt Kindig
2013-5-16
编辑:Matt Kindig
2013-5-16
This seems to work for me:
pattern = 'Platform:\s+(\d+)';
data = regexp(indata, pattern, 'tokens');
data = cell2mat(cellfun(@(x) str2double(x{:}), data, 'UniformOutput', false));
Others can be done similarly.
EDIT: implemented a better way.
更多回答(2 个)
Cedric
2013-5-16
编辑:Cedric
2013-5-16
I assumed that you forgot the Platform field in the first line of your sample data and took the following instead:
Platform: 1 Type: 1 Part ID: 23568 Time Tag: 55057.12345678
Loc ID: 1 Bar ID: 9 Past LR: 0 Isync/Osync: 1
Platform: 1 Type: 1 Part ID: 23568 Time Tag: 55123.12345678
Loc ID: 1 Bar ID: 6 Past LR: 0 Isync/Osync: 1
Platform: 23 Type: 1 Part ID: 23568 Time Tag: 55124.12345678
Loc ID: 1 Bar ID: 4 Past LR: 0 Isync/Osync: 1
Platform: 23 Type: 1 Part ID: 23568 Time Tag: 55213.12345678
Loc ID: 1 Bar ID: 9 Past LR: 0 Isync/Osync: 1
Platform: 55 Type: 1 Part ID: 23568 Time Tag: 55300.12345678
Loc ID: 1 Bar ID: 11 Past LR: 0 Isync/Osync: 1
You can get all fields as follows:
buffer = fileread('data.txt') ;
pattern = 'form:\s+(\d+).*?Tag:\s+([\d\.]+).*?Bar ID:\s+(\d+)' ;
tokens = regexp(buffer, pattern, 'tokens') ;
data = reshape(str2double([tokens{:}]), 3, []).' ;
and if you are sure that there is only one space after each sem-icolumn, you can use a simpler pattern:
pattern = 'form:\s(\d+).*?Tag:\s([\d\.]+).*?Bar ID:\s(\d+)' ;
Running this leads to a data array with the following columns:
>> data(:,1)
ans =
1
1
23
23
55
>> data(:,2)
ans =
1.0e+04 *
5.5057
5.5123
5.5124
5.5213
5.5300
>> data(:,3)
ans =
9
6
4
9
11
PS: did you see my last comment in the thread with your previous question about regexp? I think that the official doc is really well built and a fantastic resource for learning regexp! :-)
Note that depending the length of the file(s), running three times REGEXP, each time for matching one given field, might be more efficient that running it one time only with the current, more complex pattern.
EDIT: just to clarify, your first attempt was not that bad; you forgot the 'match' 3rd parameter, so REGEXP outputted positions of matches instead of matches (i.e. the first Platform was matched on character 97, the second on character 207, etc). Also your pattern would match e.g. 'Platform: 1' and not just '1'. If you want to match 'Platform: 1' but output just '1', you can either token-ize the expression matching the number in the pattern:
>> pattern_tok = 'Platform:\s(\d+)' ;
>> tokens = regexp(buffer, pattern_tok, 'tokens')
tokens =
{1x1 cell} {1x1 cell} {1x1 cell} {1x1 cell} {1x1 cell}
>> [tokens{:}]
ans =
'1' '1' '23' '23' '55'
which is what Matt proposed, or use a positive look-behind and match the number:
>> pattern_posLb = '(?<=Platform:\s)\d+' ;
>> matches = regexp(buffer, pattern_posLb, 'match')
matches =
'1' '1' '23' '23' '55'
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Characters and Strings 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!