У меня есть грязный файл журнала, из которого я хочу извлечь полезную для меня информацию. По messy, я имею в виду, что файл может содержать произвольные строки символов/чисел. Однако номерам, которые мне нужно извлечь, всегда предшествует определенная строка – new beta value =
.
Итак, пример, если мой входной файл журнала
3456789FGHJKLcvbnm,.ghjkl
Error!
Warning. GHJKL:6&*()_
new beta value = 1557.01
$%^&*()VGBNM<
GBHNM<
Warning!!!
This is a random line
new beta value = 1101.6
TL:vbNM<>%^UIOP
FGHJKL]\[;/
new beta value = 100
...
Я надеюсь читать
1557.01
1101.6
100
...
в MATLAB.
Кажется, что для этого MATLAB не имеет встроенных функций. Как я могу это достичь?
Одна реализация с использованием fgetl
queryline = 'new beta value';
fID = fopen('test.txt');
mydata = []; % Initialize data
while ~feof(fID) % Loop until we get to the end of the file
tline = fgetl(fID);
if ~isempty(strfind(tline, queryline))
% If we find a match for our query string in the line of the file
formatspec = sprintf('%s = %%f', queryline)
mydata = [mydata sscanf(tline, formatspec)];
end
end
fclose(fID);
Как предположил @excaza, есть несколько способов сделать это. Я нахожу прочитанный весь файл и использую regexp намного проще + быстрее.
indata = fileread('test.txt');
pattern = 'new beta value =\s+(\d+.\d+)'; %//the pattern you are looking for is a Stirng "new beta value =" followed by a Double (which is the integer part of the number you are looking for) + a dot(or decimal) + another Double (which is the part 2 of the number you are looking for)
lines = regexp(indata, pattern, 'tokens'); %//output as cell array
result = cell2mat(cellfun(@(x) str2double(x{:}), lines, 'UniformOutput', false)); %//output as Matrix
result =
1557.01 1101.6 100
Здесь другая реализация:
fid = fopen('file.txt', 'r');
str = reshape(fread(fid,inf,'*char'),1,[]);
fclose(fid);
numbers = str2double(regexp(str, '(?<=new beta value =\s+)\d+(.\d*)?','match')).';
Это работает следующим образом:
- Строки 1–3: содержимое файла считывается как строка.
- Строка 4: для извлечения чисел применяется регулярное выражение. Lookbehind используется для обнаружения (но не соответствия) строки. Результатом является массив ячеек строк, к которому применяется
str2double
для преобразования в вектор чисел.
Предполагаемый формат:
- Формат номера
\d+(.\d*)?
определяет номера формы100.34
или100
. Он не обнаруживает-100
,-100.34
,.34
,-.34
. Если вам тоже нужны эти случаи, вам нужно соответствующим образом изменить регулярное выражение. - Строка, которая отмечает желаемые номера, может необязательно содержать пробел перед номером (как в вашем примере). В противном случае удалите
\s+
в регулярном выражении.