MATLAB中的动态regexprep

MATLAB中的动态regexprep,regex,matlab,Regex,Matlab,我在长字符串中有以下字符串: a=b=c=d; a=b; a=b=c=d=e=f; 我想首先搜索上面提到的模式(X=Y=…=Z),然后对上面提到的每个字符串进行如下输出: a=d; b=d; c=d; a=b; a=f; b=f; c=f; d=f; e=f; 通常,我希望所有变量都与字符串最右边的最后一个变量具有等号。有没有一种方法可以在MATLAB中使用regexprep来实现这一点。对于固定长度的字符串,我可以这样做,但对于可变长度的字符串,我不知道如何实现这一点。感谢您的帮助 对

我在长字符串中有以下字符串:

a=b=c=d;
a=b;
a=b=c=d=e=f;
我想首先搜索上面提到的模式(X=Y=…=Z),然后对上面提到的每个字符串进行如下输出:

a=d;
b=d;
c=d;

a=b;

a=f;
b=f;
c=f;
d=f;
e=f;
通常,我希望所有变量都与字符串最右边的最后一个变量具有等号。有没有一种方法可以在MATLAB中使用regexprep来实现这一点。对于固定长度的字符串,我可以这样做,但对于可变长度的字符串,我不知道如何实现这一点。感谢您的帮助

对于两个等号的情况,我的尝试如下:

funstr = regexprep(funstr, '([^;])+\s*=\s*+(\w+)+\s*=\s*([^;])+;', '$1 = $3; \n $2 = $3;\n');

没有一个正则表达式可以覆盖所有的情况。如本答案所示:

但是,您有几个备选方案可以实现最终结果:

  • 您可以使用regexp获取行中的所有值,选择最后一个值,然后使用for循环迭代其他值以生成输出。获取值的正则表达式如下所示:

    matchStr=regexp(str,“([^=;\s]*)”,“match”)

  • 如果您想以任何方式使用regexprep,您应该根据输入字符串中“=”的数量编写一个模式生成器和一个替换表达式生成器,并将它们作为regexprep func的参数传递

  • 您可以忽略Regex,将输入拆分为在整个值中生成输出循环(类似于备选方案#1)


  • 我没有太多使用Matlab的经验;但是您的问题可以通过一个简单的字符串拆分函数来解决

    [parts, m] = strsplit( funstr, {' ', '='}, 'CollapseDelimiters', true )
    
    现在,存储
    零件的最后一部分
    ;然后迭代
    部分
    ,直到:

    len = length( parts )
    for i = 1:len-1
        print( strcat(parts(i), ' = ', parts(len)) )
    end
    

    我不知道matlab中的
    print
    函数到底是什么。您可以相应地更新它。

    不是regexp,但如果您坚持使用Matlab,您可以使用
    cellfun
    函数来避免循环:

    str = 'a=b=c=d=e=f;' ; %// input string
    
    list = strsplit(str,'=') ;
    strout = cellfun( @(a) [a,'=',list{end}] , list(1:end-1), 'uni', 0).' %'// Horchler simplification of the previous solution below 
    
    %// this does the same than above but more convoluted
    %// strout = cellfun( @(a,b) cat(2,a,'=',b) , list(1:end-1) , repmat(list(end),1,length(list)-1) , 'uni',0 ).'
    
    将为您提供:

    strout = 
        'a=f;'
        'b=f;'
        'c=f;'
        'd=f;'
        'e=f;'
    
    注意:正如霍奇勒在评论中正确指出的,尽管
    cellfun
    指令允许压缩代码,但它只是一个伪装的循环。此外,由于它在
    单元上运行
    ,因此速度非常慢。您不会在这些简单的输入上看到差异,但是当超级性能不是主要问题时,请继续使用


    现在,如果你喜欢正则表达式,你一定喜欢黑魔法代码。如果您的所有字符串从一开始就在一个单元格数组中,那么有一种方法可以(克服)滥用
    cellfun
    功能来隐藏您的代码,并在一行中完成所有操作

    考虑:

    strlist = {
    'a=b=c=d;'
    'a=b;'
    'a=b=c=d=e=f;'
    };
    
    然后,您可以将所有子字符串与:

    strout = cellfun( @(s)cellfun(@(a,b)cat(2,a,'=',b),s(1:end-1),repmat(s(end),1,length(s)-1),'uni',0).' , cellfun(@(s) strsplit(s,'=') , strlist , 'uni',0 ) ,'uni',0)
    >> strout{:}
    ans = 
        'a=d;'
        'b=d;'
        'c=d;'
    ans = 
        'a=b;'
    ans = 
        'a=f;'
        'b=f;'
        'c=f;'
        'd=f;'
        'e=f;'
    

    这将为您提供一个
    3x1
    单元阵列。每组子字符串一个单元格。如果您想将它们全部连接起来,那么只需:
    strall=cat(2,strout{:})

    我认为您拼错了第三个案例示例,不应该如您所述全部等于f吗?您还应该将您的尝试发布到问题上,以便far@RodrigoL奥佩斯现在都修好了。谢谢你的指点。我认为在这种情况下你可以简化你的
    cellfun
    行:
    strout=cellfun(@(a)[a',=',list{end}],list(1:end-1),'uni',0)。
    。我也不一定要调用
    cellfun
    来避免
    for
    循环,因为这是一种伪装的循环——这很方便,但不一定比使用简单的循环更快。@horchler。谢谢,很好。我纠正了给你评分的帖子,并强调了
    cellfun
    的缓慢。不过,我没有将您的简化应用到我在编辑中发布的全局解决方案:(@Hoki感谢您的回复。但我的问题不是只将字符串分解为不同的部分。我的任务是首先在长字符串中查找模式。例如,我想查找类似“X=Y=…=Z”的模式然后用较小的字符串替换它。您的解决方案假设您已经有一个模式为“X=Y=…=Z”的字符串。对于模式搜索,我需要使用regexprep@ubabd。事实上,我的解决方案在这方面对您没有帮助。很抱歉。但您的问题没有提到您刚才在评论中说的内容,而是从“我有以下条件:“……因此我的假设。你应该编辑你的问题,并提及这一重要事实。”。