从文本文件中提取特定数据

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 之前通过访问第一个元素来解包元胞。 建议的代码所做的是,对于元胞数组中的每个字符串,它都会搜索相应的组合:

  1. / - 首先查找开始的正斜杠

  2. \w*/ - 然后查找字母或数字字符 - 在遇到另一个斜杠之前至少查找这些字符中的一个。这样做的好处是您不限于第一个斜线后的一个字符。它们可以是任何字母数字字符。

  3. (.+) - 指定 group,其中在第二个斜杠之后,我们收集 space 之前的所有字符(请参阅下一点)。我们寻找所有字符,而不仅仅是字母数字的原因是因为有可能出现更多的斜杠。我们只会在遇到 space 时停止搜索(再次参见下一点)。

  4. \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)。