You can use preg_match and capture groups to match the string properly.
https://3v4l.org/K1IK4
<?php
$string = "some address number 23 neighborhood city";
preg_match("/([^\d]*\d*)(.*)$/", $string, $matches);
var_dump($matches);
array(3) {
[0]=>
string(40) "some address number 23 neighborhood city"
[1]=>
string(20) "some address number 23"
[2]=>
string(18) " neighborhood city"
}
EDIT:
In regex we want to achieve what we want with the lowest steps possible.
This is our regex: https://regex101.com/r/rihbWM/2 and we can see it requires 9 steps which is kinda good.
1st Capturing Group ([^\d]\d)
Match a single character not present in the list below [^\d]* This is performance-wise better than .*\d because .*\d matches the whole string - then has to jump back to the decimal which is worse performance-wise.
- Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
\d matches a digit (equal to [0-9])
\d* matches a digit (equal to [0-9])
- Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
2nd Capturing Group (.*)
.* matches any character (except for line terminators)
- Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
$ asserts position at the end of the string, or before the line terminator right at the end of the string (if any)
(.+[0-9]+)(.+)might basically do already.[0-9]+to match your integer, then split after the match.