MATLAB中regexp()输出如何排除非捕获部分并验证最小长度匹配
MATLAB正则提取分号前内容问题解答
问题1:如何仅捕获目标分组内的内容
你之前拿不到分组内容的核心原因是误用了非捕获分组:
- 正则里
(?:表达式)的作用是标记这个分组只参与整体匹配,不单独作为捕获结果返回,你要捕获分组内容反而加了?:前缀,自然用'tokens'参数拿不到任何结果,这和是否设置令牌名称无关——只有命名捕获(格式为(?<name>表达式))才需要指定令牌名,普通捕获分组直接用'tokens'就能按顺序返回结果。 - 如果用
'match'参数,返回的永远是整个正则表达式匹配到的完整字符串,不管你分组怎么写,都会把正则里所有匹配到的部分(包括你写的;\s?部分)一起返回,所以才会带上分号和后面的空白。
正确的捕获写法是把非捕获组改成普通捕获组,去掉?:即可,配合'tokens'参数就能只返回分组内匹配到的内容。
问题2:原表达式的匹配逻辑校验与修正
你原来写的(?:.*?);\s?在当前给出的示例里能匹配到正确的位置,但存在两个问题:
- 如问题1所说,非捕获组+
'match'的组合会返回多余的分号、空白字符,不符合你要提取内容的需求 .*?的非贪婪匹配在遇到赋值内容本身包含分号(比如字符串值里写了;)的场景时,会提前截断内容,导致匹配错误。
修正方案
方案1:正则稳妥写法
用[^;]+替代.*?,直接匹配连续的非分号字符,从逻辑上避免跨分号匹配的问题,代码如下:
example = 'S(1).a=''A''; S(1).b=''B''; S(1).c=''C''; S(1).d=''D''; \n'; % 正则说明:捕获1个以上连续非分号字符,后面紧跟分号+0或1个空白字符 expression = '([^;]+);\s?'; result = regexp(example, expression, 'tokens'); % tokens返回的是嵌套元胞数组,展开为一维元胞即可直接使用 result = [result{:}];
执行后result里的每个元素就是分号前的完整赋值语句,直接循环调用eval()即可:
for idx = 1:length(result) eval(result{idx}); end
方案2:更适合新手的非正则写法
你的需求本质是按分号拆分字符串,完全可以不用正则,用内置字符串拆分函数实现,逻辑更直观、不容易写错:
% 按分号拆分字符串 parts = strsplit(example, ';'); % 去除每个分段前后的空白,过滤掉拆分产生的空字符串 result = strtrim(parts(~cellfun(@isempty, strtrim(parts))));
这个写法得到的结果和正则写法完全一致,不需要记忆正则语法规则,更适合新手使用。
内容的提问来源于stack exchange,提问作者Argyll
相关产品推荐
相关产品推荐

