Matlab正则表达式捕获具有命名标记的组

时间:2017-04-06 02:51:25

标签: regex matlab octave regex-group

我正在尝试从matlab中的文件中读取一些文本行。使用regexp函数提取一些命名的标记。虽然八度音程中的一切都很好,但我无法在Matlab中使用相同的表达式。

我想要处理不同类型的行,例如:

line1 = 'attr enabled  True';
line2 = 'attr width  1.2';
line3 = 'attr size  8Byte';

我提出的正则表达式如下:

pattern = '^attr +(?<name>\S+) +(?:(?<number>[+-]?\d+(?:\.\d+)?)(?<unit>[a-z,A-z]*)?|(?<bool>(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE])))$'

当我跑步时(在Matlab 2016b中):

[tokens, matches] = regexp(line1, pattern, 'names', 'match');

结果如下:

tokens  = 0×0 empty struct array with fields:
             name
matches = 0×0 empty cell array

然而,八度音的结果如下:

tokens = scalar structure containing the fields:
             name = enabled
             number =
             unit =
             bool = True
matches = { [1,1] = attr enabled  True }

我用regexr.com测试了我的正则表达式,这表明octave工作正常。

一旦我从正则表达式模式中删除外部捕获组:

pattern = '^attr +(?<name>\S+) +(?<number>[+-]?\d+(?:\.\d+)?)(?<unit>[a-z,A-z]*)?|(?<bool>(?:[tT][rR][uU][eE]|[fF][aA][lL][sS][eE]))$'

Matlab输出:

tokens = struct with fields:
              bool: 'True'
              name: []
              number: []
              unit: []
matches = { True }

因此,matlab开始将其他命名标记识别为字段,但名称字段仍为空。此外,正则表达式不再是正确的交替...... 这是关于捕获组的错误还是我非常误解了什么?

2 个答案:

答案 0 :(得分:1)

一些简单的测试表明MATLAB不支持具有命名参数的嵌套非捕获组。你最好的工作可能是使用未命名的组?

x1 = 'Apple Banana Cat';

% Named groups work:
re1 = regexp(x1, '(?<first>A.+) (?<second>B.+) (?<third>C.+)', 'names')

% Non-capturing (unnamed) groups work...
re2 = regexp(x1, '(?:A.+) (?<second>B.+) (?<third>C.+)', 'names')

% Nested non-capturing group does work, but not with named groups
re3 = regexp(x1, '(?:(A.+)) (?<second>B.+) (?<third>C.+)', 'names')         % OK
re4 = regexp(x1, '(?:(A.+)) (B.+) (C.+)', 'tokens')                         % OK (unnamed)
re5 = regexp(x1, '(?:(?<first>A.+)) (?<second>B.+) (?<third>C.+)', 'names') % Not OK

可悲的是,没有单一的规范正则表达式定义,有很多口味。因此,只是因为它适用于Octave或regexr.com并不能保证它能够或应该在别处工作,特别是当你开始进入正则表达式的更具异国情调的区域时。

我认为你可能不得不解决它,尽管我很高兴被证明是错的!

(PS My test in v2016a,YMMV)。

编辑: 我现在已经在2016a和2016b“re4”作品中进行了测试,并在两者中得到了相同的结果:

>> x1 = 'Apple Banana Cat';
>> re4 = regexp(x1, '(?:(A.+)) (B.+) (C.+)', 'tokens');

>> disp(re4{1}{1})
Banana

>> disp(re4{1}{2})
Cat

答案 1 :(得分:1)

嵌套捕获组将成为问题。

我也遇到了这个问题,这让我发疯了。最后我想我发现Matlab文档解释了发生了什么:

  

注意:如果表达式具有嵌套括号,则MATLAB捕获   对应于最外面一组括号的标记。对于   例如,给定搜索模式'(and(y|rew))',MATLAB创建一个   'andrew'的令牌,但'y''rew'的令牌。

来自&#34;正则表达式&#34; Matlab文档的帮助文件:

>> web(fullfile(docroot, 'matlab/matlab_prog/regular-expressions.html#btrvwd4'))

我正在运行版本8.6.0.267246 (R2015b)

所以这是Matlab的非特征。似乎对我非常有限,但也许我错过了一些东西。