在 PHP 中,如何用空格替换变量中的制表符?

22

$data 包含制表符、前导空格和多个空格。我希望将所有制表符替换为一个空格。将多个空格替换为一个单独的空格,并删除前导空格。

实际上,我希望将这个输入数据转换成:

[    asdf asdf     asdf           asdf   ] 

输出数据中:

[asdf asdf asdf asdf]

我该如何做到这一点?


你是想要去除所有制表符,还是希望保留列格式? - Synetech
我认为你应该重新评估答案并接受不同的答案。 - Jeff
9个回答

23

使用单个空格修剪、替换制表符和额外的空格:

$data = preg_replace('/[ ]{2,}|[\t]/', ' ', trim($data));

首先,这个模式很笨重。其次,按照您编写的方式,它不会重新扫描,因此对于 tab space tab space tab space 的一组运行,它将产生多个空格。您测试过吗? - Jeff

15
$data = trim(preg_replace('/\s+/g', '', $data));

你还忘了提到去除前导空格的trim函数。可能也要提一下ltrim,因为他要求去除前导空格,然后又展示了两端。 - Matthew Scharley
是的,谢谢你指出来。在这个例子中,显示需要删除前导和尾随空格,所以我更新了我的代码。 - RaYell
preg_replace 默认替换所有匹配到的模式,除非你指定了 limit 参数。 - JustinP
12
“g”修饰符似乎不能起作用。根据http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php的说明,即使在包含换行符的文本中重复匹配同一行上的内容,php也将其视为一行,因此不需要使用“g”修饰符。 - Guillaume Bois
笔误 - 你正在用''替换空格,但你想用' '。 - Denis Pshenov
1
减一表示替换字符串,该字符串删除所有空格,甚至是OP想要在“单词”之间的单个空格。 - Jeff

4
$data = trim($data);

这将去除您的前导(和尾随)空格。

$pattern = '/\s+/';
$data = preg_replace($pattern, ' ', $data);

这将把一个或多个空格的集合转换为一个空格。

$data = str_replace("\t", " ", $data);

那会消除你的选项卡。

如果你正在使用\s,那么你就不需要\t - Jeff

4
假设方括号不是字符串的一部分,只是用于说明目的,那么:
$new_string = trim(preg_replace('!\s+!', ' ', $old_string));

你也许可以使用一个正则表达式来实现这个目标,但是这个正则表达式会相当复杂。上述方法更加简单明了。

注意:我还假设你不想将 "AB\t\tCD"(\t 是一个制表符)替换为 "AB CD"。


这应该是被接受的答案。我发表了我的答案,只是为了反驳你用 preg_replace 去修剪字符串是“复杂的”这个说法。 - Jeff
美丽的回答。谢谢。 - Milad Ghiravani

2
$new_data = preg_replace("/[\t\s]+/", " ", trim($data));

如果你正在使用\s,那么你就不需要\t - Jeff

0

如果您需要删除 

$data = trim(preg_replace('/\s+|nbsp;/g', '', $data));

0

经过很多挫折,我发现这是最好的解决方案,因为它还可以删除两个字符长的不间断空格:

$data = html_entity_decode(str_replace(' ',' ',htmlentities($data))); $data = trim(preg_replace('/\h/', ' ', $data)); // 可替换比\s更多的空格字符类型

请参见billynoah


0

这个答案完全按照问题的字面意思回答:它仅仅关注空格和制表符。当然,提问者可能也想包括其他种类的空白字符在被修剪/压缩的范围内,但让我们假装他想保留嵌入的CR和/或LF

首先,让我们设置一些常量。这将有助于理解和可维护性,如果需要修改的话。我加了一些额外的空格,以便您更容易地比较相似之处和不同之处。

define( 'S', '[ \t]+'      ); # Stuff you want to compress; in this case ONLY spaces/tabs
define( 'L', '/\A'.S.'/'   ); # stuff on the Left edge will be trimmed
define( 'M',   '/'.S.'/'   ); # stuff in the Middle will be compressed
define( 'R',   '/'.S.'\Z/' ); # stuff on the Right edge will be trimmed
define( 'T', ' '           ); # what we want the stuff compressed To

我们正在使用\A\Z转义字符来指定主题的开头和结尾,而不是典型的基于行的^$元字符。这并不是因为它们在这种情况下是必需的,而是出于“防御性”编程,以防将来S的值发生变化需要它们。

现在是秘密酱汁:我们将利用preg_replace的一些特殊语义,即(强调添加)

如果替换数组中的元素少于模式数组中的元素,则任何额外的模式都将被替换为空字符串。

function trim_press( $data ){
    return preg_replace( [ M, L, R ], [ T ], $data );
}

因此,我们不是使用一个模式字符串和替换字符串,而是使用一个模式数组和替换数组,这将导致额外的模式 LR 被删除。


-1

只需使用此正则表达式

$str = trim(preg_replace('/\s\s+/', ' ', $str));

它将用一个空格替换所有的制表符和空格。

这里正则表达式中的符号+表示出现一次或多次, 模式意味着无论何处有两个或更多个空格,都将其替换为一个空格。


2
如果一个模式无法匹配单个制表符,那么扣一分(并且在发布之前没有测试您的解决方案也要扣一分)。 - Jeff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接