从文本文件中提取特定数据
Extract specific data from a text file
我有一个 txt 文件出现在记事本++中,如下所示:
/a/apple 1
/b/bat 10
/c/cat 22
/d/dog 33
/h/human/female 34
现在我想提取末尾数字之前第二个斜线之后的所有内容。所以我想要的输出是:
out = {'apple'; 'bat'; 'cat'; 'dog'; 'human/female'}
我写了这段代码:
file= fopen('file.txt');
out= textscan(file,'%s','Delimiter','\n');
fclose(file);
它给出:
out =
{365×1 cell}
out{1} =
'/a/apple 1'
'/b/bat 10'
'/c/cat 22'
'/d/dog 33'
'/h/human/female 34'
如何从文本文件中获取所需的输出(如果可能,直接获取)?或者任何正则表达式,如果直接获得所需的输出是不可能的?
你快到了。
file = fopen('file.txt');
out = textscan(file, '%s', 'Delimiter', '\n');
parsed = cellfun(@(x) textscan(x, '/%c/%s %d'), out{1}, 'uniformoutput', false);
parsed = cellfun(@(x) x{2}, parsed, 'uniformoutput', false);
fclose(file);
另一种选择是使用 MATLAB 中的 regular expressions using the already created cell array of strings you have, but then cleverly pulling out what you need based on a specified input pattern that you want to search for within each of the strings in your cell array. Use the regexp
函数来实现:
% Your code
file= fopen('file.txt');
out = textscan(file,'%s','Delimiter','\n');
fclose(file);
% Proposed changes
out = regexp(out{1}, '/\w*/(.+)\s', 'tokens', 'once');
out = [out{:}].';
回想一下 textscan
将 return 单个元素的元胞数组,因此您需要在使用 regexp
之前通过访问第一个元素来解包元胞。
建议的代码所做的是,对于元胞数组中的每个字符串,它都会搜索相应的组合:
/
- 首先查找开始的正斜杠
\w*/
- 然后查找字母或数字字符 - 在遇到另一个斜杠之前至少查找这些字符中的一个。这样做的好处是您不限于第一个斜线后的一个字符。它们可以是任何字母数字字符。
(.+)
- 指定 group,其中在第二个斜杠之后,我们收集 space 之前的所有字符(请参阅下一点)。我们寻找所有字符,而不仅仅是字母数字的原因是因为有可能出现更多的斜杠。我们只会在遇到 space 时停止搜索(再次参见下一点)。
\s
- 寻找 space
会搜索这个特定的字符集合,其实就是遇到space之前的文字。请注意,我必须在组 (.+)
之后用 space 分隔,否则它基本上会 return 在第二个斜线之后整行。您需要在那里限制字符串内的搜索。
第 3 点中的 ()
很重要,因为 regexp
中的 'tokens'
属性允许您额外提取位于组中的字符串。使用 'once'
仅提取第一个匹配项。请注意,输出将是一个嵌套的单元格数组,其中每个单元格都是一个元素,表示组内的匹配项。我们可以使用 comma-separated lists 解压单元格并将它们全部连接成一个单元格数组。我们转置以便我们保持您想要的柱状向量。
当你这样做时,我们得到以下信息:
>> out
out =
5×1 cell array
'apple'
'bat'
'cat'
'dog'
'human/female'
不过,我认为您对内容而不是数据的形状更感兴趣,因此如果您愿意,可以删除转置。这种方法的好处是不需要 cellfun
因为 regexp
隐式循环。
您可以直接从 textscan
获得所需的输出,无需任何进一步处理:
file = fopen('file.txt');
out = textscan(file, '/%c/%s %d');
fclose(file);
out = out{2}
out =
5×1 cell array
'apple'
'bat'
'cat'
'dog'
'human/female'
请注意format specifier string will be treated as literal text to ignore in the output. Any additional slashes will be captured in the string (%s
). Also, it is unnecessary to specify a delimiter argument中的两个斜杠,因为默认分隔符是空格,所以尾随数字将被捕获为一个单独的数值(%d
)。
我有一个 txt 文件出现在记事本++中,如下所示:
/a/apple 1
/b/bat 10
/c/cat 22
/d/dog 33
/h/human/female 34
现在我想提取末尾数字之前第二个斜线之后的所有内容。所以我想要的输出是:
out = {'apple'; 'bat'; 'cat'; 'dog'; 'human/female'}
我写了这段代码:
file= fopen('file.txt');
out= textscan(file,'%s','Delimiter','\n');
fclose(file);
它给出:
out =
{365×1 cell}
out{1} =
'/a/apple 1'
'/b/bat 10'
'/c/cat 22'
'/d/dog 33'
'/h/human/female 34'
如何从文本文件中获取所需的输出(如果可能,直接获取)?或者任何正则表达式,如果直接获得所需的输出是不可能的?
你快到了。
file = fopen('file.txt');
out = textscan(file, '%s', 'Delimiter', '\n');
parsed = cellfun(@(x) textscan(x, '/%c/%s %d'), out{1}, 'uniformoutput', false);
parsed = cellfun(@(x) x{2}, parsed, 'uniformoutput', false);
fclose(file);
另一种选择是使用 MATLAB 中的 regular expressions using the already created cell array of strings you have, but then cleverly pulling out what you need based on a specified input pattern that you want to search for within each of the strings in your cell array. Use the regexp
函数来实现:
% Your code
file= fopen('file.txt');
out = textscan(file,'%s','Delimiter','\n');
fclose(file);
% Proposed changes
out = regexp(out{1}, '/\w*/(.+)\s', 'tokens', 'once');
out = [out{:}].';
回想一下 textscan
将 return 单个元素的元胞数组,因此您需要在使用 regexp
之前通过访问第一个元素来解包元胞。
建议的代码所做的是,对于元胞数组中的每个字符串,它都会搜索相应的组合:
/
- 首先查找开始的正斜杠\w*/
- 然后查找字母或数字字符 - 在遇到另一个斜杠之前至少查找这些字符中的一个。这样做的好处是您不限于第一个斜线后的一个字符。它们可以是任何字母数字字符。(.+)
- 指定 group,其中在第二个斜杠之后,我们收集 space 之前的所有字符(请参阅下一点)。我们寻找所有字符,而不仅仅是字母数字的原因是因为有可能出现更多的斜杠。我们只会在遇到 space 时停止搜索(再次参见下一点)。\s
- 寻找 space
会搜索这个特定的字符集合,其实就是遇到space之前的文字。请注意,我必须在组 (.+)
之后用 space 分隔,否则它基本上会 return 在第二个斜线之后整行。您需要在那里限制字符串内的搜索。
第 3 点中的 ()
很重要,因为 regexp
中的 'tokens'
属性允许您额外提取位于组中的字符串。使用 'once'
仅提取第一个匹配项。请注意,输出将是一个嵌套的单元格数组,其中每个单元格都是一个元素,表示组内的匹配项。我们可以使用 comma-separated lists 解压单元格并将它们全部连接成一个单元格数组。我们转置以便我们保持您想要的柱状向量。
当你这样做时,我们得到以下信息:
>> out
out =
5×1 cell array
'apple'
'bat'
'cat'
'dog'
'human/female'
不过,我认为您对内容而不是数据的形状更感兴趣,因此如果您愿意,可以删除转置。这种方法的好处是不需要 cellfun
因为 regexp
隐式循环。
您可以直接从 textscan
获得所需的输出,无需任何进一步处理:
file = fopen('file.txt');
out = textscan(file, '/%c/%s %d');
fclose(file);
out = out{2}
out =
5×1 cell array
'apple'
'bat'
'cat'
'dog'
'human/female'
请注意format specifier string will be treated as literal text to ignore in the output. Any additional slashes will be captured in the string (%s
). Also, it is unnecessary to specify a delimiter argument中的两个斜杠,因为默认分隔符是空格,所以尾随数字将被捕获为一个单独的数值(%d
)。