我尝试了12个与你的类似的字符串,它完美地工作了:
function str_to_address($context) {
$context_parts = array_reverse(explode(" ", $context));
$zipKey = "";
foreach($context_parts as $key=>$str) {
if(strlen($str)===5 && is_numeric($str)) {
$zipKey = $key;
break;
}
}
$context_parts_cleaned = array_slice($context_parts, $zipKey);
$context_parts_normalized = array_reverse($context_parts_cleaned);
$houseNumberKey = "";
foreach($context_parts_normalized as $key=>$str) {
if(strlen($str)>1 && strlen($str)<6 && is_numeric($str)) {
$houseNumberKey = $key;
break;
}
}
$address_parts = array_slice($context_parts_normalized, $houseNumberKey);
$string = implode(' ', $address_parts);
return $string;
}
这里假设房屋号码至少有两位数,但不超过六位数。同时也假设邮政编码不是“扩展”形式(例如12345-6789)。然而,这可以很容易地修改以适应该格式(在此处使用正则表达式是一个不错的选择,例如
(\d{5}-\d{4})
)。
但是,在解析用户输入数据时使用正则表达式并不是一个好主意,因为我们不知道用户将输入什么,因为没有任何验证(可以想象)。
从代码和逻辑开始,首先从上下文中创建数组并获取邮政编码:
// split the context (for example, a sentence) into an array,
// so we can loop through it.
// we reverse the array, as we're going to grab the zip first.
// why? we KNOW the zip is 5 characters long*.
$context_parts = array_reverse(explode(" ", $context));
// we're going to store the array index of the zip code for later use
$zipKey = "";
// foreach iterates over an object given the params,
// in this case it's like doing...
// for each value of $context_parts ($str), and each index ($key)
foreach($context_parts as $key=>$str) {
// if $str is 5 chars long, and numeric...
// an incredibly lazy check for a zip code...
if(strlen($str)===5 && is_numeric($str)) {
$zipKey = $key;
// we have what we want, so we can leave the loop with break
break;
}
}
整理一下,这样我们就能更好地获取房屋号码的对象。
$context_parts_cleaned = array_slice($context_parts, $zipKey);
$context_parts_normalized = array_reverse($context_parts_cleaned);
然后,让我们使用与邮政编码相同的基本逻辑来获取门牌号码:
$houseNumberKey = "";
foreach($context_parts_normalized as $key=>$str) {
if(strlen($str)>1 && strlen($str)<6 && is_numeric($str)) {
$houseNumberKey = $key;
break;
}
}
// we probably have the parts we for the address.
// let's do some more cleaning
$address_parts = array_slice($context_parts_normalized, $houseNumberKey);
// and build the string again, from the address
$string = implode(' ', $address_parts);
// and return the string
return $string;