Регулярное выражение в matlab с [,] - PullRequest
1 голос
/ 20 октября 2011

Я читаю CSV-файл в Matlab следующим образом.

data_f = fopen(fileName,'r');
while(~feof(data_f))
    line_f = fgetl(data_f);
    Temp(1,:) = regexp(line_f, ',', 'split');
end

Моя проблема в том, что некоторые столбцы в строке имеют данные формата [a,b].Поэтому, когда я пытаюсь использовать регулярное выражение только с ',' в качестве разделителя, оно выдает ошибку.Итак, как мне написать регулярное выражение для этой цели.

Например: значения CSV-файла

12,23,a,3,[1,2],5

Мне нужно следующее

12 23 a 3 [1,2] 5

, а не так

12 23 a 3 1 2 5

Ответы [ 3 ]

1 голос
/ 20 октября 2011

Я думаю, что для этой цели лучше использовать библиотеку синтаксического анализатора CSV. Но если у вас есть причина использовать регулярное выражение, вы можете использовать это

,(?=[^]]*(\[|$))

Это не будет работать, если у вас нет вложенных []

Объяснение: Соответствует ,, за которым следует любое количество не ] символов, за которым следует либо [, либо $ (конец строки)

1 голос
/ 21 октября 2011

Как утверждают другие, было бы лучше использовать выделенную библиотеку синтаксического анализатора CSV ... Тем не менее, вот одно из возможных решений:

file.csv

12,23,aaaaa,3,[1,2,3,4,5],5
222,33,b,4,[2],6
32,43,c,5,[3,4],7
42,534,ddd,6,[4,5,0],8
52,63,e,7,[5,6],9

MATLAB

%# cell array to hold the data
C = cell(0,6);

%# read file line-by-line
fid = fopen('file.csv','rt');
while ~feof(fid)
    tline = fgetl(fid);

    %# get [...] tokens and their locations (assuming there is one per line)
    [tok tokExt] = regexp(tline, '\[(.*)\]', 'tokens', 'tokenExtents', 'once');

    %# replace commas with space in tokens, and place back into line
    tline(tokExt(1):tokExt(2)) = strrep(tok{1},',',' ');

    %# split line by commas and store the parts read
    C(end+1,:) = textscan(tline, '%f %f %s %f %s %f', 'Delimiter',',');
end
fclose(fid);

%# reduce nested level of cell array
C(:,3) = vertcat(C{:,3});
C(:,5) = vertcat(C{:,5});

Результат чтения файла примера выше:

>> C
C = 
    [ 12]    [ 23]    'aaaaa'    [3]    '[1 2 3 4 5]'    [5]
    [222]    [ 33]    'b'        [4]    '[2]'            [6]
    [ 32]    [ 43]    'c'        [5]    '[3 4]'          [7]
    [ 42]    [534]    'ddd'      [6]    '[4 5 0]'        [8]
    [ 52]    [ 63]    'e'        [7]    '[5 6]'          [9]

Очевидно, это массив ячеек, напечатанный в командной строке (MATLAB использует [] для обозначения записей матрицы, поэтому не путайте их с скобками, считанными из файла) ..

Если вы хотите получить числовые значения пятого столбца, вы можете использовать STR2NUM:

C(:,5) = cellfun(@str2num, C(:,5), 'UniformOutput',false)
1 голос
/ 20 октября 2011

Следующий код рассекает строку s = '3,4, [5,6], a, 2'

s='3,4,[5,6],a,2'
bracket=false;
i=1;
A=[];

while ~isempty(s)
  if s(i)==',' && bracket==false
    A(end+1)=s(1:i-1);
    s(1:i)=[] 
    i=1; 
  end 
  if s(i)=='[' 
    bracket=true; 
  end 
  if s(i)==']'
    bracket=false; 
  end 
  i=i+1; 
  if i>length(s) 
    i=i-1; 
    A(end+1)=s(1:i);
    s(1:i)=[]; 
  end 
end

-редактировать после перечитывания вашего вопроса-

...