2

I have a string that contains a name followed by a town. So like John Smith Smithville.

I need to separate this out into two variables (name, town) or an array.

I have an array of town names to check against. Whats the best way to separate the string into two once the town name is found in the string?

$string = "John Smith Smithville";
$townlist = array("smithville", "janeville", "placeville");

if(contains($string,$townlist))
{
//separate into two variables

}

3 Answers 3

6

This uses regex to do it.

  • Get an escaped version of town names for regex. Make sure none of your names town names have a / in them, or we can't use array_map() (preg_quote()'s 2nd argument is the delimiter).
  • Join them with the pipe |.
  • String build and run the regex.
  • The $matches will have name as 1 and and town as 2 indexes.

PHP

$string = 'John Smith Smithville';
$townlist = array('smithville', 'janeville', 'placeville');

if (preg_match_all(
      '/^(.*)\s(' . implode('|', array_map('preg_quote', $townlist)) . ')$/i',
      $string,
      $matches
))
{
    var_dump($matches);
}

It works!

Output

array(3) {
  [0]=>
  array(1) {
    [0]=>
    string(21) "John Smith Smithville"
  }
  [1]=>
  array(1) {
    [0]=>
    string(10) "John Smith"
  }
  [2]=>
  array(1) {
    [0]=>
    string(10) "Smithville"
  }
}
Sign up to request clarification or add additional context in comments.

Comments

1

This does the trick I think

  • For each item in the list, get the position in the original string
  • If we get a position, we know it is in the string
  • Create an array of the first part and the second part
  • Break from the loop, since we found what we needed
  • Return the value
  • Returns an empty array if we don't find anything

Should work, did a few tests.

$string = "John Smith Smithville";
$townlist = array("smithville", "janeville", "placeville");

function stringSeperation($string, $list)
{
    $result = array();

    foreach($list as $item)
    {
        $pos = strrpos(strtolower($string), strtolower($item));
        if($pos !== false)
        {
            $result = array(trim(substr($string, 0, $pos)), trim(substr($string, $pos)));
            break;
        }
    }

    return $result;
}

var_dump(stringSeperation($string, $townlist));

Comments

0

Have you think about "special cases", such as: "John Smith New York"? or "New York New York" (the name can contains space, and person name can be the same with the city)

I think that the more approriate solution is: for every string str, we check with all the city name. The check procedure is (pseudo code):

foreach str in strArray[]
  foreach city in cities

     tmp = Get the substring in the end of str, which equal the length of the "city"
     if (tmp == city) then {name = substring(str, 0, strlen(str) - strlen(tmp)); break;}

4 Comments

I'd be interested to meet a person named New York :) My solution will still work if the person's name is New York New York I think.
Maybe I don't fully understand, but it may has troubles with "New York" (name) - "Unknown City"? That's just my concern.
I've fixed mine to work with the edge case "New York New York", changed strpos to strrpos
After putting more thought into it, I see that all answers is nice. But it doesn't solve all the possible problems, which roots from the data itself. Such as, if in the list of cities, we have both "York" and "New York" as valid cities. Maybe (if you can) a simple "-" seperator will help. But that's a little too far here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.