我想从文本文件中提取一个数字。 首先,我读取文件并导入为以下形式的单元格数组:
A = {
'1 0 0 0 - 0: 0.000741764'
'2 0 0 0 - 0: 100'
'3 0 0 0 - 0: 100'
'4 0 0 0 - 0: 100'
'5 0 0 0 - 0: 0.00124598'
'6 0 0 0 - 0: 0.000612725'
'7 0 0 0 - 0: 0.000188365'
'8 0 0 0 - 0: 0'
'9 0 0 0 - 0: 0'
'10 0 0 0 - 0: 0'
'11 0 0 0 - 0: 0'
'12 0 0 0 - 0: 0'};
我需要根据左整数的值得到右边的数字。 例如,我需要知道对应于3和6(100和0.000612725)的值:
'3 0 0 0 - 0: 100'
'6 0 0 0 - 0: 0.000612725'
这是我的代码:
clear all
close all
clc
A = {
'1 0 0 0 - 0: 0.000741764'
'2 0 0 0 - 0: 100'
'3 0 0 0 - 0: 100'
'4 0 0 0 - 0: 100'
'5 0 0 0 - 0: 0.00124598'
'6 0 0 0 - 0: 0.000612725'
'7 0 0 0 - 0: 0.000188365'
'8 0 0 0 - 0: 0'
'9 0 0 0 - 0: 0'
'10 0 0 0 - 0: 0'
'11 0 0 0 - 0: 0'
'12 0 0 0 - 0: 0'};
THREE = 3;
SIX = 6;
M = cellfun(@str2num, A, 'UniformOutput', false);
Values = cell2mat(M);
Index_3 = find(Values(:,1) == SIX);
Index_6 = find(Values(:,1) == SIX);
sp_3 = strsplit(A{Index_3},':');
sp_6 = strsplit(A{Index_6},':');
VALUE_3 = str2double(sp_3(end));
VALUE_6 = str2double(sp_6(end));
但我得到了一个错误:
Error using cat
Dimensions of matrices being concatenated are not consistent.
Error in cell2mat (line 84)
m{n} = cat(1,c{:,n});
Error in test (line 23)
Values = cell2mat(M);
,这是因为:
M =
[1x4 double]
[1x104 double]
[1x104 double]
[1x104 double]
[1x4 double]
[1x4 double]
[1x4 double]
[1x4 double]
[1x4 double]
[1x4 double]
[1x4 double]
[1x4 double]
我试过了:
str2double
相反,但我得到M中所有值的NaN。
答案 0 :(得分:3)
这是使用regular expressions的完美案例。正则表达式是在文本中寻找模式的强大工具。在您的情况下,您首先想要找到的是开始字符串的数字。接下来,您要在字符串末尾找到相应的数字。您还在评论中提到,您可以使用指数表示法获取数字(类似2.50652e-007
)。这也可以轻松处理,我将把它添加为您的单元格数组中的另一个条目,以证明这是有效的。
我将如何进行是因为我将处理整个单元格数组。我之所以这样做,是因为我确定你需要查看其他数字,而不仅仅是第三和第六项,所以如果我们先这样做,那么它会非常容易你得到你需要的其他东西。
我们可以在两个正则表达式regexp
调用中提取开始值和结束值,以提取开头和结尾,如下所示:
%// Your code to define A and also new entry with exponential notation
A = {
'1 0 0 0 - 0: 0.000741764'
'2 0 0 0 - 0: 100'
'3 0 0 0 - 0: 100'
'4 0 0 0 - 0: 100'
'5 0 0 0 - 0: 0.00124598'
'6 0 0 0 - 0: 0.000612725'
'7 0 0 0 - 0: 0.000188365'
'8 0 0 0 - 0: 0'
'9 0 0 0 - 0: 0'
'10 0 0 0 - 0: 0'
'11 0 0 0 - 0: 0'
'12 0 0 0 - 0: 0',
'13 0 0 0 - 0: 2.50652e-007'};
%// Begin new code
beginStr = regexp(A, '^\d+', 'match');
endStr = regexp(A, '(\d*\.?\d+(e-\d+)?)$', 'match');
看起来有点复杂,但很容易解释。 regexp
默认情况下接受两个参数:字符串或单元格数组(例如您的情况)和要搜索的模式。我还选择了标志'match'
,因为我想要返回实际的字符串。默认情况下,regexp
会返回匹配发生位置的索引。
第一次regexp
次调用会查找在字符串的开头处出现的数字序列。 \d+
表示查找一个或多个数字,^
表示在字符串的开头查看,因此将这两个结合起来表示您正在寻找对于字符串开头的数字序列。我假设字符串的开头是一个整数,所以我们可以侥幸逃脱。将返回的是一个单元格数组,其中每个条目都是另一个匹配的单元格数组。如果这样做,我们应该得到一个包含1 x 1个单元格的单元格数组,每个单元格都是开头的数字。
第二个regexp
调用会查找一系列数字,以便有一堆数字(\d*
),后跟一个可选的小数点(\.?
),然后是至少有1个号码(\d+
)然后可选我们会在此之后查找e
个字符,-
字符和另一堆数字{{1} }。请注意,这些都是通过(\d+)
组合在一起的,这意味着这个指数内容是可选的。此外,整个模式都出现在字符串的 end ,因此括号将所有这些标记组合在一起并以(e-\d+)?
结尾,这意味着查看结尾串即可。 $
字符表示查找零次或多次出现,*
字符表示查找零次或一次出现。同样,?
字符表示要查找一个或多个匹配项。
请注意,正则表达式中的+
字符表示通配符或任何字符。如果您明确希望与小数点匹配,则需要在.
字符前添加\
。因此,正则表达式是在字符串末尾找到模式,我们可以选择在可选小数点之前有一堆数字,然后在这两个可选项之后至少有一个数字。这将类似于第一个.
调用的输出,但在字符串的末尾有数字。
让我们使用regexp
进行仔细检查:
celldisp
对我来说很好看!现在,您的最终任务是将数字转换为double。我们可以使用>> format compact
>> celldisp(beginStr)
beginStr{1}{1} =
1
beginStr{2}{1} =
2
beginStr{3}{1} =
3
beginStr{4}{1} =
4
beginStr{5}{1} =
5
beginStr{6}{1} =
6
beginStr{7}{1} =
7
beginStr{8}{1} =
8
beginStr{9}{1} =
9
beginStr{10}{1} =
10
beginStr{11}{1} =
11
beginStr{12}{1} =
12
beginStr{13}{1} =
13
>> celldisp(endStr)
endStr{1}{1} =
0.000741764
endStr{2}{1} =
100
endStr{3}{1} =
100
endStr{4}{1} =
100
endStr{5}{1} =
0.00124598
endStr{6}{1} =
0.000612725
endStr{7}{1} =
0.000188365
endStr{8}{1} =
0
endStr{9}{1} =
0
endStr{10}{1} =
0
endStr{11}{1} =
0
endStr{12}{1} =
0
endStr{13}{1} =
2.50652e-007
电话,就像您为我们做的那样:
cellfun
beginNumbers = cellfun(@(x) str2double(x{1}), beginStr);
endNumbers = cellfun(@(x) str2double(x{1}), endStr);
和beginNumbers
将包含我们转换后的号码。让我们将这些放入矩阵并显示它的样子:
endNumbers
我使用out = [beginNumbers endNumbers];
format long g;
来显示尽可能多的有效数字。这就是我们得到的:
format long g
酷!现在,如果您想要第三个和第六个数字,只需执行:
>> out
out =
1 0.000741764
2 100
3 100
4 100
5 0.00124598
6 0.000612725
7 0.000188365
8 0
9 0
10 0
11 0
12 0
13 2.50652e-07
以上内容为您提供整行,但如果您特别想要与ID一起使用的相应数字,请执行以下操作:
>> third = out(3,:)
third =
3 100
>> sixth = out(6,:)
sixth =
6 0.000612725