tags:

views:

36

answers:

2

I need to split (but not preg_split()) my title on /, : or whitespace, in that order. For example, if I split on /, then I don't want to bother looking for : or whitespace.

I thought I could do it with a regex (the input string here will never have HTML in it)

$delimiters = array('/', ':', '\s');

$title = preg_replace('@(' . implode('|', $delimiters) . ')(.*)$@', '$1 <span>$2</span>', $title, 1);

The regex I have will match the first space, and not bother with the others. This is not what I want.

Obviously I could strpos() for the other characters (: and /) and remove the \s from the delimiters if it found the others. This will solve the first problem.

I also want to pick the furthest right match, i.e. if splitting a sentence on whitespace, I want the last word to be matched.

Do I need to use preg_split() here, and preserver the delimiter or can I do it with one regex?

Thanks

A: 

While I was waiting to be answered, I came up with this, and it works!

$delimiters = array('/', ':');

if ( ! preg_match('@(?:' . implode('|', $delimiters) . ')@', $title)) {
   $delimiters[] = '\s';
}

$tokens = preg_split('@(' . implode('|', $delimiters) . ')@', $title, NULL, PREG_SPLIT_DELIM_CAPTURE);

$tokens[count($tokens) - 1] = '<span>' . end($tokens) . '</span>'; 

$title = implode($tokens);
alex
See this [here](http://ideone.com/w4CWQ). Does the output look right to you?
NullUserException
@NullUserException `alex()`? Haha! Well, sort of. I forgot to mention that these strings should only ever have one `:` or `\`. But perhaps I should make it more bulletproof. Thanks!
alex
@NullUserException Actually, that behaviour is OK. :) Also, looks like my `/` didn't come out in my previous comment. (think I accidentally did the escape)
alex
Are you just trying to put the first "word" from right to left inside a tag?
NullUserException
@NullUserException I want the right hand side of the last `/` or `:`, or if none of those chars are present, than I want the last word. Don't ask me - this is how the designer wants titles displayed! :P
alex
+1  A: 

Well, here's another one:

function alexify($title) {
    $delimiters = array('/', ':', '\s');

    $regex = '@(' . implode('|', $delimiters) . ')([^' . implode($delimiters) . ']*)$@';
    $title = preg_replace($regex, '$1<span>$2</span>', $title, 1);

    return $title;
}

It appears to produce the same output as your function: http://ideone.com/HVeh5

EDIT: It actually produces different output for the 3rd string. I don't know which one is supposed to be the right one.

NullUserException
Thanks! So your regex looks for text on the right hand side of a delimiter that doesn't contain a delimiter! Brilliant!
alex
@alex There's one thing that hasn't been accounted for: some characters (regex metacharacters) need to be escaped for the regex to work.
NullUserException
So long as I only use `/`, `:` and `\s`, I should be right, right? I specifically used the @ symbols as delimiters so I didn't need to escape the `/`. :)
alex
@alex Yeah, in that case you should be OK. But there's always [`preg_quote()`](http://php.net/manual/en/function.preg-quote.php) if you need it.
NullUserException