与this问题相关,我将此数据样本保存在.txt文件中:
'1458937887.70818 $GPGGA,200228.90,3555.3269,N,15552.9641,A*25'
'1458937887.709668 $GPVTG,56.740,T,56.740,M,
0.069,N,0.127,K,D*2D'
'1458937887.712022 $GPGGA,200229.00,3555.3269,N,
15552.9641,C*2B'
'1458937887.714071 $GPVTG,286.847,T,286.847,M,0.028,N,0.051,K,D*28'
我使用以下内容来阅读数据:
textscan(fileID,'%s','Delimiter','\n')
然而,\n
不是我想要的。我想将另一个分隔符定义为字母(字母数字),后跟*
,后跟两个字母(字母数字),然后是\n
。
修改 主要问题是一些数据被保存为两行。例如,上面的第2行和第3行属于同一个数据包。
答案 0 :(得分:2)
我的一个建议是将整个文件作为单个字符串阅读。然后你可以做的是删除自己放在文件中的新行。执行此操作后,使用正则表达式在找到所需的模式后插入新的换行符,该模式是一个字母数字字符,后跟一个星号*
,后跟两个字母数字字符。一旦我们最终获得了这一点,请使用带有textscan
标记的Delimiter
将字符串与我们放入的新换行符分开。
首先使用fread
从文件中读取数据。我们可以通过读取无限量的字符来轻微滥用此命令,这意味着它将读取整个文件直到结束。我们还需要确保指定此文件中的每个离散元素都是一个字符。完成此操作后,我们会搜索任何换行符并将其删除。如果你在Windows上,它不仅引入了换行符,而且还引入了回车符,但我将编写的代码将独立于该事实。我们确实需要知道换行符是ASCII码10,回车符是ASCII码13. fread
的输出实际上是double
数组,其中每个元素都是字符的ASCII码在文件中看到。我们将使用logical
索引删除这些元素,然后使用regexprep
搜索所需的模式并自行插入换行符。一旦我们这样做了,我们最终会把它扔进textscan
,就像你调用它一样。
因此:
fileID = fopen('...'); %// Place filename here
str = fread(fileID, [1 inf], 'char'); %// Read in the string as one array
%// Remove newlines and carriage returns (if applicable)
str(str == 10 | str == 13) = [];
%// Search for the desired pattern and insert newlines after the pattern
out = regexprep(char(str), '\w\*\w{2}', '$0\n');
%// Finally split up the strings
txt = textscan(out, '%s', 'Delimiter', '\n');
txt = txt{1};
%// Close the file
fclose(fileID);
当我们使用regexprep
时,我们搜索字母数字字符\w
,后跟星号\*
(此处\
非常重要,因为*
是在正则表达式语言中用于表示其他内容。要表示正则表达式中的实际字符*
,必须使用\
字符前缀),后跟两个字母数字字符\w{2}
。结果将是您的文件中的这些事件一起从字符串中删除。另一个复杂因素是我们必须强制转换为char
才能将原来为double
类型的字符串转换为char
。此外,在这种情况下,textscan
的输出应该为您提供一个元素的嵌套单元格数组,因此我们通过引用第一个单元格来解包单元格。所需的输出位于txt
。