读未知长度线

时间:2014-12-11 15:35:13

标签: regex string matlab parsing text-processing

我有一个未知的长度行,格式为

bobaboao dsaas : 5->2  2->3  4->6  7->2  1->4  5->1  8->1  222->1  23->13 ...

我需要阅读每个

"X->Y" 

并发送到功能

Dist(X,Y)

直到行尾

我怎样才能在MATLAB中做到这一点?

3 个答案:

答案 0 :(得分:3)

我的一个建议是使用regular expressions,以便在示例中搜索特定于一个ID的字符串中的子字符串,然后是->,后跟另一个ID。一旦我们在您的字符串中找到这些确切的模式,我们只需将它们提取出来并将它们放入单元格数组中。换句话说,假设我们的字符串存储在s中(我实际上将使用您的示例),请执行以下操作:

s = 'bobaboao dsaas : 5->2  2->3  4->6  7->2  1->4  5->1  8->1  222->1  23->13';
g = regexp(s, '[0-9]+->[0-9]+', 'match');

让我们慢慢浏览一下这段代码。 s存储您正在分析的字符串,然后下一行找到字符串s中的子字符串,该子字符串找到至少一个数字的序列,后跟->,然后是至少一位数。 'match'标志提取出与我们在s中找到的此模式匹配的字符串。 g是此行的输出,每个字符串都存储在单元格数组中。我们得到:

g = 

  Columns 1 through 7

    '5->2'    '2->3'    '4->6'    '7->2'    '1->4'    '5->1'    '8->1'

  Columns 8 through 9

    '222->1'    '23->13'

请注意,存储到单元格数组很重要,因为每个子字符串的长度可能不同。

一旦我们提取了这些子字符串,我们可以做的是提取之前的数字和<{strong>之后的提取数字->。我们只需应用两个正则表达式调用来获取前后的数字:

X = regexp(g, '^[0-9]+', 'match');
Y = regexp(g, '[0-9]+$', 'match');

第一个调用在g中以数字开头的每个字符串的开头查找子字符串,而第二个调用在g中以每个字符串结尾处查找子字符串数。将返回的是单元格数组中包含的数字。此外,数字本身是字符串。因为单元格中的每个元素都是一个字符串,我们应该将它们转换回实际数字。我们还应将它们放入数字向量中,以便与代码一起使用:

X = cellfun(@str2double, X);
Y = cellfun(@str2double, Y);

cellfun是一个允许您将特定函数应用于单元格数组中每个单元格的函数。在这种情况下,我们希望将单元格数组中的每个数字转换为double的字符串。因此,请使用str2double来促进此转化。完成后,我们将获得数字向量,在->之前和->之后为您提供数字。

我们终于得到了:

X =

     5     2     4     7     1     5     8   222    23

Y =

     2     3     6     2     4     1     1     1    13

答案 1 :(得分:3)

我将regexp'tokens'一起使用,它会在括号(())之间拉出匹配位:

>> C = regexp(s,'(\d*)->(\d*)','tokens')
C = 
    {1x2 cell}    {1x2 cell}    {1x2 cell}    {1x2 cell}    {1x2 cell}   ...
    {1x2 cell}    {1x2 cell}    {1x2 cell}    {1x2 cell}
>> xy = str2double(vertcat(C{:})).'
xy =
     5     2     4     7     1     5     8   222    23
     2     3     6     2     4     1     1     1    13

然后你有X = xy(1,:);Y = xy(2,:);

解释:\d是一个数字([0-9]),\d*表示任意数量的数字。将它们包裹在()中会使它们成为令牌。整个模式定义匹配,但令牌被提取到单元阵列的单元阵列中,每个匹配一个单元阵列,包含令牌的单元阵列。使用vertcat制作单个矩阵很容易,并将其转换为str2double

答案 2 :(得分:1)

我找到了一个棘手的方法:

0)通过写下以下行删除字母序列:

  str(1:strfind(str,':'))=''

1)以下列方式连接此字符串:

newStr=['[',str,']']

,现在你的新字符串将是:&#39; [5-> 2 2-> 3 4-> 6 7-> 2 1-> 4 5-> 1 8- &gt; 1 222-> 1 23-&gt; 13]&#39;

2)删除所有&#39;&gt;&#39; ,你可以通过以下命令来完成:

newStr(newStr=='>')=''

,现在您将拥有&#39; [5-2 2-3 4-6 7-2 1-4 5-1 8-1 222-1 23-13]&#39;, 请注意,这实际上是一个字符串,表示包含数字之间距离的向量,这导致我们进入第3步......

3)评估我们获得的字符串:

distances=eval(newStr);

如果你想要没有+ a - 的距离,只需使用abs()函数。