在字符串中,PHP如何在大写字母前放置一个空格(正则表达式)

39
我有许多字符串包含一些单词被挤在一起,我需要将它们分开。
例如: ThisWasCool - This Was Cool MyHomeIsHere - My Home Is Here 我正在逐渐理解正则表达式,并且我相信我应该使用preg_replace来完成这个任务。我的问题是如何编写表达式以查找匹配项。
我只做到了这一步:
   preg_replace('~^[A-Z]~', " ", $string)
每个字符串都包含很多单词,但仅第一个单词包含组合单词,因此使用我上面的示例,一个字符串将是
"ThisWasCool to visit you again" - "This Was Cool to visit you again"
我已经告诉它从开头开始查找大写字母,但我不知道如何做到: - 仅限于每个字符串的第一个单词 - 如何在空格后重新使用替换部分的大写字母

1
“\ n”替换。您是指空格还是换行符? - MitMaro
这里已经很晚了,我是指空格,通常我会直接输入“ ”,但那可能是错误的! - Paul M
4个回答

91

问题

  1. 你的正则表达式 '~^[A-Z]~' 只会匹配第一个大写字母。请查看元字符以获取有关模式语法的更多信息。

  2. 你的替换是一个换行符 '\n' 而不是一个空格。

解决方案

使用以下代码:

$String = 'ThisWasCool';
$Words = preg_replace('/(?<!\ )[A-Z]/', ' $0', $String);

(?<!\ )是一种断言,它将确保我们不会在已经有空格的大写字母之前添加空格。


你如何跳过第一个大写字母前的空格? - Eineki
10
我明白了:preg_replace('/(?<! )(?<!^)[A-Z]/',' $0', $String)的意思是在$String字符串中,将除了句首和已有空格之外的大写字母前面添加一个空格。 - Eineki
22
如果您需要一个不会将连续的大写字母分开的翻译(例如,BusinessUnitID 应该是 Business Unit ID,而不是 Business Unit I D),那么您可以使用 /(?<! )(?<!^)(?<![A-Z])[A-Z]/。 - Dave

15
$string = preg_replace('/[A-Z]/', ' $0', $string);

也许在此之后,可以通过ltrim函数处理结果。

$string = ltrim(preg_replace('/[A-Z]/', ' $0', $string));

谢谢,我猜“/”是分隔符,有没有办法限制它只在第一个单词上工作呢?这些数据来自 CSV 文件,所以第一个单词被包裹在“ ”中。 - Paul M
有的。我建议使用ltrim去除空格,但你也可以在表达式中使用:/\B[A-Z]/ - Alex Barrett

3

以下是我的意见,这个版本只会在第一个单词上起作用,并保留大写字母序列(BMW)。

$str = "CheckOutMyBMW I bought it yesterday";
$parts = explode(' ', $str);
$parts[0] = preg_replace('~([a-z])([A-Z])~', '\\1 \\2', $parts[0]);
$newstr = implode(' ', $parts);
echo $newstr;

1
我对正则表达式不熟悉,但是我建议你使用类似下面的代码:
$string="ThisWasCool to visit you again";
$temp = explode(' ',$string, 2);
$temp[0] = preg_replace('/(.)([A-Z])/','$1 $2', $temp[0]);
$string = join(' ',$temp);

看了一下SirLancelot的代码,我有第二个解决方案。不过我还是更喜欢使用explode函数来解决问题,因为你说你只需要获取字符串中的第一个单词。
$string="ThisWasCool to visit you again";
$temp = explode(' ',$string, 2);
$temp[0] = preg_replace('/(?<!^)([A-Z])/',' $0', $temp[0]);
$string = join(' ',$temp);

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