You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写正则移除换行及后续空白符,实现字符串忽略格式比对

问题描述

我想要实现的效果是忽略格式差异,断言两个字符串相等,示例代码如下:

$expected =
    '<div class="input select">
        <label for="countries">User Country</label>
        <select name="countries" id="countries">
            <option value="">Select a country</option>
            <option value="ger">Germany</option>
            <option value="fra">France</option>
            <option value="rus" selected="selected">Russia</option>
        </select>
    </div>';
$actual = '<div class="input select"><label for="countries">User Country</label><select name="countries" id="countries"><option value="">Select a country</option><option value="ger">Germany</option><option value="fra">France</option><option value="rus" selected="selected">Russia</option></select></div>';
$this->assertTextEquals($expected, $actual);

我目前实现的断言方法代码如下:

public function assertTextEquals($expected, $actual)
{
    $actualNoLineBreaks = preg_replace("/\r|\n/", "", $actual);
    $actualNoLongSpaces = preg_replace('!\s+!', ' ', $actualNoLineBreaks);
    $expectedNoLineBreaks = preg_replace("/\r|\n/", "", $expected);
    $expectedNoLongSpaces = preg_replace('!\s+!', ' ', $expectedNoLineBreaks);
    TestCase::assertEquals($expectedNoLongSpaces, $actualNoLongSpaces);
}

现在的问题是原换行符位置仍残留空格,比如会出现select"> <label的情况,和压缩后的实际字符串不匹配。
我需要一个正则可以移除换行符及其后所有连续空白字符,直到匹配到第一个非空白字符为止。我不想直接移除所有空格,否则报错信息可读性会很差,请问有没有更优雅的解决方案?


解决方案

你可以直接用/[\r\n]+\s*/这个正则表达式匹配目标内容,一次性替换为空字符串即可解决残留空格的问题。
这个正则的匹配逻辑:

  • [\r\n]+ 匹配所有换行格式(兼容Windows的\r\n、Linux的\n、老版Mac的\r)
  • \s* 匹配紧随换行之后的所有连续空白字符(包括空格、制表符等)
    将匹配到的内容直接替换为空,就可以完全清除换行和对应缩进空白,不会在原换行位置残留多余空格,同时标签内部的正常空格(比如属性值、元素文本中的空格)会被完整保留,不会影响报错可读性。

修正后的完整断言方法如下:

public function assertTextEquals($expected, $actual)
{
    // 清除所有换行及紧随换行的连续空白
    $cleanExpected = preg_replace('/[\r\n]+\s*/', '', $expected);
    $cleanActual = preg_replace('/[\r\n]+\s*/', '', $actual);

    // 如果你需要额外合并文本内部的连续多空格为单个空格,可以保留下面两行,不需要直接删除即可
    // $cleanExpected = preg_replace('/\s+/', ' ', $cleanExpected);
    // $cleanActual = preg_replace('/\s+/', ' ', $cleanActual);

    TestCase::assertEquals($cleanExpected, $cleanActual);
}

按以上方法处理后,你示例中的select"> <label会被转换为select"><label,和压缩后的$actual字符串完全匹配,断言可以正常通过。


内容的提问来源于stack exchange,提问作者bancer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 16:39:03