【问题标题】:Matlab regex - replace substring ONLY within angled bracketsMatlab 正则表达式 - 仅在尖括号内替换子字符串
【发布时间】:2015-03-02 04:29:41
【问题描述】:

我想找到一种方法来将字符串 s 中的字符 _ 替换为被空格包围的自身。唯一困难的部分是,只有在尖括号内找到子字符串时,我才尝试替换子字符串。例如(空格是故意的):

s= 'the quick <_brown _little_fox >, jumped over_the_fence .

wantedresult = the quick < _ brown _ little _ fox>, jumped over_the_fence.

如果两边已经有空间,那么获得额外的空间就很好了。

我尝试了以下方法,但没有成功: regexprep(s, <[\w ]+(\_)[\w ]+>', ' $1 ');

我想我理解上述不起作用的原因,但考虑到括号内可能有多个_,我不确定如何继续。

任何建议将不胜感激。提前致谢!

【问题讨论】:

    标签: regex string matlab


    【解决方案1】:

    与其尝试在单个regex 中执行此操作,不如尝试提取<> 之间的所有字符串,找到那些具有_ 字符的字符并用空格包围这些字符,然后重建最终的字符串?我会首先使用regexp 来查找字符串中那些有<> 包围字符串的区域,然后执行我上面提到的操作......所以先这样做:

    [st, en, match] = regexp(s, '<.*?>', 'start', 'end', 'match')
    

    这会找到所有在子字符串周围有&lt;&gt; 的字符串。 startend 标志确定字符串中开始和结束索引中的哪些索引与我们正在查找的内容匹配。在我们的例子中,start 告诉您每个 &lt; 字符在哪里,end 告诉您每个 &gt; 字符在哪里。 match 是一个字符串元胞数组,与我们对 &lt;&gt; 子字符串的搜索相匹配。这些分别存储在stenmatch中。完成后,让我们在 match 上添加一个 regexprep,并在 _ 字符前后放置空格。

    final_match = regexprep(match, '_', ' _ ');
    

    现在要重构最终的字符串,我们首先将字符从开头放置到第一个 &lt; 出现,然后我们将编写一个循环将所有内容拼凑在一起,然后当我们找到最后一个 &gt; 字符, 将所有字符加到最后.... 就像这样:

    final_string = s(1:st(1)-1);
    for idx = 1 : numel(final_match)-1
        final_string = [final_string final_match{idx}];
        final_string = [final_string s(en(idx)+1:st(idx+1)-1)];
    end
    final_string = [final_string final_match{end} s(en(end)+1:end)];
    

    第一行从原始字符串中提取内容,直到第一次出现&lt; 字符。接下来,对于&lt;&gt; 字符之间的每个子字符串(也包括这些字符),我们将修改后的字符串放置在_ 字符之间,然后我们在&gt; 字符之间访问这些字符当前子字符串到下一个子字符串的&lt; 字符,我们重复这个过程,直到我们碰到最后一个&lt; 字符。一旦我们点击了最后一个&lt; 字符,我们就放置最后一个&lt;&gt; 修改后的子字符串,最后将原始字符串的最后一个片段放在末尾。如果我们在您的示例中使用上面的代码,我们会得到:

    final_string = 
    
    the quick < _ brown  _ little _ fox >, jumped over_the_fence.
    

    如果我们修改了字符串s,那么我们得到:

    s =
    
    the quick <_brown _little_fox >, < _jumped _over _the_ fence>.
    

    我用上面的代码得到的输出是:

    final_string =
    
    the quick < _ brown  _ little _ fox >, <  _ jumped  _ over  _ the _  fence>.
    

    如您所见,_ 字符之间的所有单词在&lt;&gt; 字符之间都有空格。但是,这仅在至少有一个&lt;&gt; 字符序列时才有效。如果没有,则上面的代码不起作用。因此,您需要检查match(或startend)是否至少有一个元素。如果是,则继续执行上述代码。如果没有,就吐出原来的字符串。

    【讨论】:

    • 单字建议:&lt;.*&gt; to &lt;.*?&gt;;否则s=[s,s] 将导致'&lt;_brown _little_fox &gt;, jumped over_the_fence .the quick &lt;_brown _little_fox &gt;' 的贪婪匹配,而不是&lt;_brown _little_fox &gt; 的两倍。 [因此替换 over_the_fence 下划线。](我不确定 for 循环是否已经正确工作。)
    • @knedlsepp - 我以为我把? 字符放在那里是为了懒惰的评估......我发誓我做到了。感谢您的指正。这可能是您更正的第 100000 个帖子。我想我一半的名声应该归你。
    • 更像是第四或第五。 ;-) 好吧,你写的答案很有趣,所以当我偶然发现一个我认为值得回答的问题并且你已经给出了答案时,我一定会看看你的方法,偶尔会发现一个小错字。
    • 完美运行。我想这可能会很干净。谢谢大家!
    • @Manbearpig - 是的,除了将字符串拆分为&lt;&gt; 子字符串并处理每个子字符串之外,我想不出任何其他方法:(。如果有人最终找到了更好的方法,我很想听听。顺便说一句,不客气!
    猜你喜欢
    • 1970-01-01
    • 2021-11-10
    • 2019-11-08
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-06
    相关资源
    最近更新 更多