【问题标题】:Extract only words from a cell array in matlab仅从matlab中的单元格数组中提取单词
【发布时间】:2015-11-19 18:45:52
【问题描述】:

我有一组包含来自 html 页面的预处理文本的文档。他们已经给了我。我只想从中提取单词。我不希望提取任何数字或常用词或任何单个字母。我面临的第一个问题就是这个。

假设我有一个元胞数组:

{'!' '!!' '!!!!)'  '!!!!thanks' '!!dogsbreath'    '!)'    '!--[endif]--'    '!--[if'}

我想让单元格数组只有单词 - 像这样。

{'!!!!thanks' '!!dogsbreath' '!--[endif]--' '!--[if'}

然后把这个转换成这个元胞数组

{'thanks' 'dogsbreath' 'endif' 'if'}

有什么办法吗?


更新要求:感谢您的所有回答。但是我面临一个问题!让我来说明这一点(请注意,单元格值是从 HTML 文档中提取的文本,因此可能包含非 ASCII 值) -

{'!/bin/bash'    '![endif]'    '!take-a-long'    '!–photo'}

这给了我答案

{'bin'    'bash'    'endif'    'take'    'a'    'long'    'â'    'photo' }

我的问题:

  • 为什么 bin/bash 和 take-a-long 被分成三个单元格?这对我来说不是问题,但仍然是为什么?这可以避免吗。我的意思是来自单个单元格的所有单词都被合并为一个。
  • 请注意,在'!–photo' 中存在一个非ascii 字符â,它本质上表示a。是否可以合并一个步骤以使这种转换是自动的?
  • 我注意到文本"it? __________ About the Author:" 给了我"__________" 作为一个词。为什么会这样?
  • 同样,文本"2. areoplane 3. cactus 4. a_rinny_boo... 5. trumpet 6. window 7. curtain ... 173. gypsy_wagon..." 返回一个单词为'areoplane' 'cactus' 'a_rinny_boo' 'trumpet' 'window' 'curtain' 'gypsy_wagon'。我希望 'a_rinny_boo'''gypsy_wagon'a' 'rinny' 'boo' 'gypsy' 'wagon'。这个可以吗?

更新 1 根据所有建议,我写下了一个函数,它可以完成除上述两个新问题之外的大部分事情。

function [Text_Data] = raw_txt_gn(filename)

% This function will convert the text documnets into raw text
% It will remove all commas empty cells and other special characters
% It will also convert all the words of the text documents into lowercase

T = textread(filename, '%s');

% find all the important indices
ind1=find(ismember(T,':WebpageTitle:'));
T1 = T(ind1+1:end,1);

% Remove things which are not basically words
not_words = {'##','-',':ImageSurroundingText:',':WebpageDescription:',':WebpageKeywords:',' '};

T2 = []; count = 1;
for j=1:length(T1)    
    x = T1{j};
    ind=find(ismember(not_words,x), 1);
    if isempty(ind)

        B = regexp(x, '\w*', 'match');
        B(cellfun('isempty', B)) = []; % Clean out empty cells
        B = [B{:}]; % Flatten cell array

        % convert the string into lowecase
        % so that while generating the features the case sensitivity is
        % handled well
        x = lower(B);        

        T2{count,1} = x;
        count = count+1;
    end
end
T2 = T2(~cellfun('isempty',T2));


% Getting the common words in the english language
% found from Wikipedia
not_words2 = {'the','be','to','of','and','a','in','that','have','i'};
not_words2 = [not_words2, 'it' 'for' 'not' 'on' 'with' 'he' 'as' 'you' 'do' 'at'];
not_words2 = [not_words2, 'this' 'but' 'his' 'by' 'from' 'they' 'we' 'say' 'her' 'she'];
not_words2 = [not_words2, 'or' 'an' 'will' 'my' 'one' 'all' 'would' 'there' 'their' 'what'];
not_words2 = [not_words2, 'so' 'up' 'out' 'if' 'about' 'who' 'get' 'which' 'go' 'me'];
not_words2 = [not_words2, 'when' 'make' 'can' 'like' 'time' 'no' 'just' 'him' 'know' 'take'];
not_words2 = [not_words2, 'people' 'into' 'year' 'your' 'good' 'some' 'could' 'them' 'see' 'other'];
not_words2 = [not_words2, 'than' 'then' 'now' 'look' 'only' 'come' 'its' 'over' 'think' 'also'];
not_words2 = [not_words2, 'back' 'after' 'use' 'two' 'how' 'our' 'work' 'first' 'well' 'way'];
not_words2 = [not_words2, 'even' 'new' 'want' 'because' 'any' 'these' 'give' 'day' 'most' 'us'];

for j=1:length(T2)
    x = T2{j};
    % if a particular cell contains only numbers then make it empty
    if sum(isstrprop(x, 'digit'))~=0
        T2{j} = [];
    end
    % also remove single character cells
    if length(x)==1
        T2{j} = [];
    end
    % also remove the most common words from the dictionary
    % the common words are taken from the english dicitonary (source
    % wikipedia)
    ind=find(ismember(not_words2,x), 1);
    if isempty(ind)==0
        T2{j} = [];
    end
end

Text_Data = T2(~cellfun('isempty',T2));

更新 2 我在 here 中找到了这段代码,它告诉我如何检查非 ascii 字符。在 Matlab 中将这段代码 sn-p 合并为

% remove the non-ascii characters
if all(x  < 128)
else
  T2{j} = [];
end

然后删除空单元格似乎满足了我的第二个要求,尽管包含部分非 ascii 字符的文本完全消失了。


我的最终要求可以完成吗?其中大部分与角色'_''-'有关。

【问题讨论】:

    标签: matlab


    【解决方案1】:

    一个regexp的方法直接进入最后一步:

    A = {'!' '!!' '!!!!)'  '!!!!thanks' '!!dogsbreath'    '!)'    '!--[endif]--'    '!--[if'};
    
    B = regexp(A, '\w*', 'match');
    B(cellfun('isempty', B)) = []; % Clean out empty cells
    B = [B{:}]; % Flatten cell array
    

    匹配任何字母、数字或下划线字符。对于示例案例,我们得到一个1x4 元胞数组:

    B = 
    
        'thanks'    'dogsbreath'    'endif'    'if'
    

    编辑:

    为什么 bin/bash 和 take-a-long 被分成三个单元格?这对我来说不是问题,但仍然是为什么?这可以避免吗。我的意思是来自单个单元格的所有单词都被组合成一个。

    因为我正在展平单元格数组以删除嵌套单元格。如果删除B = [B{:}];,每个单元格内部都会有一个嵌套单元格,其中包含输入单元格数组的所有匹配项。你可以随意组合这些。

    请注意,在“!”中存在一个非 ascii 字符——它本质上意味着 a。是否可以合并一个步骤以使这种转换是自动的?

    是的,你必须根据字符代码来制作它。

    我注意到文本“它?__________ 关于作者:”给了我“__________”这个词。为什么会这样?

    正如我所说,正则表达式匹配字母、数字或下划线字符。您可以更改过滤器以排除 _,这也将解决第四个要点:B = regexp(A, '[a-zA-Z0-9]*', 'match'); 这将仅匹配 a-zA-Z0-9。这也将排除非 ASCII 字符,它们似乎与 \w* 标志匹配。

    【讨论】:

    • 我更喜欢这种方法。它对我来说更自然。
    • @excaza 能否请您解释一下如何使用字符代码将非 ascii 字符转换为 ascii 字符?
    • @roni 我建议再问一个问题,这个主题与这个主题有很大不同,答案可以帮助许多其他人。
    【解决方案2】:

    我认为@excaza 的解决方案将是首选方法,但这里有一个替代方法,isstrprop 使用其可选输入参数'alpha' 来查找字母 -

    A(cellfun(@(x) any(isstrprop(x, 'alpha')), A))
    

    示例运行 -

    >> A
    A = 
        '!'    '!!'    '!!!!)'    '!!!!thanks'    '!!dogsbreath'    '!)'    '!--[endif]--'    '!--[if'
    >> A(cellfun(@(x) any(isstrprop(x, 'alpha')), A))
    ans = 
        '!!!!thanks'    '!!dogsbreath'    '!--[endif]--'    '!--[if'
    

    要到达最终目的地,您可以稍微调整一下这种方法,就像这样 -

    B = cellfun(@(x) x(isstrprop(x, 'alpha')), A,'Uni',0);
    out = B(~cellfun('isempty',B))
    

    示例运行 -

    A = 
        '!'    '!!'    '!!!!)'    '!!!!thanks'    '!!dogsbreath'    '!)'    '!--[endif]--'    '!--[if'
    out = 
        'thanks'    'dogsbreath'    'endif'    'if'
    

    【讨论】:

    • 简洁的功能:) 感谢分享!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-10
    • 1970-01-01
    相关资源
    最近更新 更多