如何使用自定义分隔符读取数据

How to read data using a custom delimiter

关于 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行属于同一个数据包。

我的一个建议是将 整个 文件作为单个字符串读取。然后你可以做的是自己删除文件中的新行。执行此操作后,在找到所需模式后使用正则表达式插入新的换行符,该模式是一个字母数字字符,后跟一个星号 *,然后是两个字母数字字符。一旦我们终于有了它,使用 textscanDelimiter 标志通过我们输入的新换行符分隔字符串。

先用fread to read in data from a file. We can slightly abuse this command by reading an infinite amount of characters, which means it will read the entire file until the end. We also need to make sure that we specify that each discrete element in this file is a character. Once we do this, we search for any newline characters and remove them. If you are on Windows, not only does it introduce newlines but it also introduces carriage returns but the code I will write will be independent of that fact. We do need to know that the newline is ASCII code 10 and the carriage return is ASCII code 13. The output of fread will in fact be a double array where each element is the ASCII code of a character seen in the file. We will use logical indexing to remove these elements, then use 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}', '[=10=]\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.