Matlab正则表达式;环顾两个表达式中的任何一个

Matlab regexp; lookaround for either one of two expressions

我有一个 table,其中有一列是文件名字符串。 文件名有不同的格式:

str ={... 
'filename',...
'filename_suffix',...
'filenamesuffix'};

我正在尝试使用 regexp 来提取每个文件名的 后缀 部分(并为没有后缀的文件接收 '' )使用代码(注意后缀可以是任意一组字符,包括下划线):

regexp(str,'(?<=filename(_|)).*','match','emptymatch')

不幸的是,这给了我输出(展开输出单元格之后):

ans = 

{''}


ans = 

'_suffix'


ans = 

'suffix'

具体来说,它不会像我在编写 filename(_|) 时所期望的那样忽略第二个后缀中的 _,我理解为 尝试匹配 filename_ 如果找不到,请尝试匹配 filename 但显然我误读了那一行。

任何人都可以帮助我使用 2 个选项之一实现 环顾四周

首先,Matlab正则表达式,lookbehind不能在替代分支内有替代。

将模式扩展为

regexp(str,'(?<=filename_|filename).*','match','emptymatch')
            ^^^^^^^^^^^^^^^^^^^^^^^

(?<=filename_|filename) 回顾将需要 filename_filename 出现在除换行符 (.*) 之外的 0+ 个字符之前。 *但是,lookaround 只是检查文本而不使用它。您允许 filenamefilename_ 在匹配之前。所以,引擎一个字符一个字符地检查左边的上下文,一旦它等于filename,它就匹配其余的

如果您只需要不带_的后缀,可以使用以下解决方案之一:

ntoks = regexp(str, '(?<=filename_|filename)(?!_).*', 'match','emptymatch');

lookbehind 与 lookahead (?!_) 相结合,如果在当前位置之后有 _ 则匹配失败(这意味着如果 filename__sometext), 或

ntoks = regexp(str, 'filename_?(.*)', 'tokens','emptymatch');

其中 _ 是可选的 ? 量词。

要获取捕获的部分,您需要使用'tokens',而不是'match'。参见 Tokens in Regular Expressions

demo

另一种计算时间更少的方法可以通过使用外键 tokens 和捕获组来实现:

str ={'filename','filename_suffix','filenamesuffix'};

result=regexp(str,'filename_?(.*)','tokens','emptymatch','once');

celldisp(result)

注: 我添加了 'once' 选项,因为单元格字符串中的每个单元格似乎只有一个文件名。如果您选择删除它,结果将是元胞数组的元胞数组。