tags:

views:

838

answers:

4

I have a number of strings which contain words which are bunched together and I need to seperate them up.

For example ThisWasCool - This Was Cool
MyHomeIsHere - My Home Is Here

Im slowly getting my head around regular expressions and I believe to do this I should use preg_replace. My problem is putting together the expression to find the match.

I have only got this far

   preg_replace('~^[A-Z]~', " ", $string)

Each string contains a lot of words, but ONLY the first word contains bunched words so using my example above a string would be
"ThisWasCool to visit you again" - "This Was Cool to visit you again"

I have told it to start at the beginning, and look for capitals, but what I dont know how to do is - restrict it only to the first word of each string - how to reuse the capital letter in the replace part after the space

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

Maybe run the result through ltrim after.

$string = ltrim(preg_replace('/[A-Z]/', ' $0', $string));
Alex Barrett
Thanks I guess the / are delimiters, is there a way to restrict it to only working on the first word? The data is coming from a csv so the first word is wrapped in " "?
Paul M
Yes, there is. I suggested using ltrim to remove the space, but you could also do it in the expression with: /\B[A-Z]/
Alex Barrett
+3  A: 

Problem

  1. Your regex '~^[A-Z]~' will match only the first capital letter. Check out Meta Characters in the Pattern Syntax for more information.

  2. Your replacement is a newline character '\n' and not a space.

Solution

Use this code:

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

The (?<!\ ) is an assertion that will make sure we don't add a space before a capital letter that already has a space before it.

sirlancelot
How you can skip the space for the first capital letter?
Eineki
I've got it: preg_replace('/(?<! )(?<!^)[A-Z]/',' $0', $String);
Eineki
A: 

I'm not proficient with regular expression bat I would suggest something like the following code:

$string="ThisWasCool to visit you again";
$temp = explode(' ',$string, 2);
$temp[0] = preg_replace('/(.)([A-Z])/','$1 $2', $temp[0]);
$string = join(' ',$temp);

Looking at SirLancelot code I've got a second solution. Still I prefer the explode solution as you stated that your target it is only the first word of the string.

$string="ThisWasCool to visit you again";
$temp = explode(' ',$string, 2);
$temp[0] = preg_replace('/(?<!^)([A-Z])/',' $0', $temp[0]);
$string = join(' ',$temp);
Eineki
+1  A: 

Here's my .02c, this version will only act on the first word, and will preserve sequences of uppercase letters (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;
too much php