【问题标题】:Insert at most one leading and trailing newline after each word在每个单词后最多插入一个前导和尾随换行符
【发布时间】:2015-08-07 12:34:55
【问题描述】:

我有包含分隔符的字符串。分隔符需要包含前导和尾随换行符,但它们不需要。三个例子:

[heading 1]content[heading 2]content[heading 3]content

[heading 1]content↵
[heading 2]content↵
[heading 3]content

[heading 1]↵
content[heading 2]↵
content[heading 3]↵
content

我需要使用正则表达式查找替换来规范化数据。每个分隔符必须有前导和尾随换行符,第一个分隔符只能有尾随换行符:

[heading 1]↵
content↵
[heading 2]↵
content↵
[heading 3]↵
content

我已经尝试过这种查找替换模式 (regexr),但它并非在所有情况下都有效:

find: \[.+?\](?!\r\n)
repl: $0\r\n

更新:我更喜欢一个只包含一个正则表达式的解决方案,它不需要诸如替换和修剪等预处理和后处理。

【问题讨论】:

    标签: php regex string preg-match


    【解决方案1】:

    正则表达式

    \s*(\[[^[\]]+])\s*
    

    在标题\[[^[\]]+] 前后搜索分隔符\s* 并将其删除。将捕获的标题前后输出为"\n\1\n"

    可用于

    $input="[heading 1]content[heading 2]content[heading 3]content
    
    [heading 1]content
    [heading 2]content
    [heading 3]content
    
    [heading 1]
    content[heading 2]
    content[heading 3]
    content";
    $str=substr(preg_replace('\s*(\[[^[\]]+])\s*',"\n\1\n",$input),1);
    

    生成以下内容:

    [heading 1]
    content
    [heading 2]
    content
    [heading 3]
    content
    [heading 1]
    content
    [heading 2]
    content
    [heading 3]
    content
    [heading 1]
    content
    [heading 2]
    content
    [heading 3]
    content
    

    【讨论】:

    • 使用trim,而不是substr
    • 另外你需要关心你需要"\n"而不是'\n'的报价
    • 也没有g修饰符。
    • @Rizier 和 Uchiha 感谢您的更正 - 目前我的办公室太热了 ;-)
    • 有没有可能放弃substr 功能?
    【解决方案2】:

    这应该适合你:

    首先只需用str_replace() 替换所有新行,然后您可以轻松地在每个[heading]content 之后添加一个新行,用preg_replace(),例如

    <?php
    
        $str = "[heading 1]content[heading 2]content[heading 3]content";
        $str = trim(preg_replace("/(\[.+?\])((?:[^\[])+)/", "$1" . PHP_EOL . "$2" . PHP_EOL, str_replace(PHP_EOL, "", $str)));
    
        highlight_string($str);
    
    ?>
    

    输出:

    [heading 1]
    content
    [heading 2]
    content
    [heading 3]
    content
    

    编辑:

    如果你只想使用正则表达式,你可以这样做:

    <?php
    
        $str = "[heading 1]content[heading 2]content[heading 3]content
    
    [heading 1]content
    [heading 2]content
    [heading 3]content
    
    [heading 1]
    content[heading 2]
    content[heading 3]
    content";
    
        $str = preg_replace("/\s*(\[.+?\]|(?![^\[]+$(*PRUNE))[^\[]+)\s*/", "$1" . PHP_EOL, $str);
        var_dump($str);
    
    ?>
    

    【讨论】:

    • [已更正] 好的,你有一个正则表达式,但它为测试用例 2 添加了 两个 换行符。@cars10 为我指明了正确的方向。
    猜你喜欢
    • 1970-01-01
    • 2022-09-26
    • 2013-02-10
    • 2017-01-02
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 2021-03-27
    • 1970-01-01
    相关资源
    最近更新 更多