정규식에서 가장 큰 것은 아니지만 여기에는 우편 번호와 함께 또는없는 2 자의 상태를 찾는 장면이 있습니다.
정규식 : 당신이 국가와 우편 번호가 함께있는 경우에만 일치 할 경우 (([A-Z]{2})|[0-9]{5})+
Fiddle
그러나, 이것 좀보세요 : 정규식 : (([A-Z]{2})(\s*[0-9]{5}))+
Fiddle
을
희망이 조금 도움이됩니다.
이 출력해야 위의 코드에서 예제를 사용하여 편집
class Extract {
private $_string;
private $_sections = array();
private $_output = array();
private $_found = array();
private $_original_string;
private $_countries = array (
'United States',
'Canada',
'Mexico',
'France',
'Belgium',
'United Kingdom',
'Sweden',
'Denmark',
'Spain',
'Australia',
'Austria',
'Italy',
'Netherlands'
);
private $_zipcon = array();
private $ZIPREG = array(
"United States"=>"^\d{5}([\-]?\d{4})?$",
"United Kingdom"=>"^(GIR|[A-Z]\d[A-Z\d]??|[A-Z]{2}\d[A-Z\d]??)[ ]??(\d[A-Z]{2})$",
"Germany"=>"\b((?:0[1-46-9]\d{3})|(?:[1-357-9]\d{4})|(?:[4][0-24-9]\d{3})|(?:[6][013-9]\d{3}))\b",
"Canada"=>"^([ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ])\s*(\d[ABCEGHJKLMNPRSTVWXYZ]\d)$",
"France"=>"^(F-)?((2[A|B])|[0-9]{2})[0-9]{3}$",
"Italy"=>"^(V-|I-)?[0-9]{5}$",
"Australia"=>"^(0[289][0-9]{2})|([1345689][0-9]{3})|(2[0-8][0-9]{2})|(290[0-9])|(291[0-4])|(7[0-4][0-9]{2})|(7[8-9][0-9]{2})$",
"Netherlands"=>"^[1-9][0-9]{3}\s?([a-zA-Z]{2})?$",
"Spain"=>"^([1-9]{2}|[0-9][1-9]|[1-9][0-9])[0-9]{3}$",
"Denmark"=>"^([D-d][K-k])?(|-)?[1-9]{1}[0-9]{3}$",
"Sweden"=>"^(s-|S-){0,1}[0-9]{3}\s?[0-9]{2}$",
"Belgium"=>"^[1-9]{1}[0-9]{3}$"
); // thanks to http://www.pixelenvision.com/1708/zip-postal-code-validation-regex-php-code-for-12-countries/
public function __construct($string) {
$this->_output = array (
"state" => "",
"city" => "",
"country" => "",
"zip" => "",
"street" =>"",
"number" => ""
);
$this->_original_string = $string;
$this->_string = $this->normalize(trim($string));
// create an array of patterns in order to extract zip code using the country list we already have
foreach($this->ZIPREG as $country => $pattern) {
$this->_zipcon[] = $pattern = preg_replace(array("/\^/","/\\$/"),array("",""), $pattern);
}
$this->init();
}
protected function init() {
$this->getData(); // get data that can be found without breaking up the string.
$this->_sections = array_filter(explode(',', trim($this->_string))); // split each section
if(!empty($this->_sections)) {
foreach($this->_sections as $i => $d) {
$d = preg_replace(array("/\s+/", "/\s([?.!])/"), array(" ","$1"), $d);
$this->_sections[$i] = trim($this->normalize($d)); // normalize strin to have one spacing between each word
}
} else {
$this->_sections[] = $this->_string;
}
// try to match what's missing with has already been found
$notFound = $this->getNotFound();
if(count($notFound)==1 && count($this->_found)>1) {
$found = $this->getFound();
foreach($found as $string) {
$notFound[0] = preg_replace("/$string/i", "", $notFound[0]);
}
$this->_output["city"] = $notFound[0];
$this->_found[] = $this->_output["city"];
$this->remove($this->_output["city"]);
}
}
public function getSections() {
return $this->_sections;
}
protected function normalize($string) {
$string = preg_replace(array("/\s+/", "/\s([?.!])/"), array(" ","$1"), trim($string));
return $string;
}
protected function country_from_zip($zip) {
$found = "";
foreach($this->ZIPREG as $country => $pattern) {
if(preg_match ("/".$pattern."/", $zip)) {
$found = $country;
break;
}
}
return $found;
}
protected function getData() {
$container = array();
// extract zip code only when present beside state, or else five digits are meaningless
if(preg_match ("/[A-Z]{2,}\s*(".implode('|', $this->_zipcon).")/", $this->_string)){
preg_match ("/[A-Z]{2,}\s*(".implode('|', $this->_zipcon).")/", $this->_string, $container["state_zip"]);
$this->_output["state"] = $container["state_zip"][0];
$this->_output["zip"] = $container["state_zip"][1];
$this->_found[] = $this->_output["state"] . " ". $this->_output["zip"];
// remove from string once found
$this->remove($this->_output["zip"]);
$this->remove($this->_output["state"]);
// check to see if we can find the country just by inputting zip code
if($this->_output["zip"]!="") {
$country = $this->country_from_zip($this->_output["zip"]);
$this->_output["country"] = $country;
$this->_found[] = $this->_output["country"];
$this->remove($this->_output["country"]);
}
}
if(preg_match ("/\b([A-Z]{2,})\b/", $this->_string)) {
preg_match ("/\b([A-Z]{2,})\b/", $this->_string, $container["state"]);
$this->_output["state"] = $container["state"][0];
$this->_found[] = $this->_output['state'];
$this->remove($this->_output["state"]);
}
// if we weren't able to find a country based on the zip code, use the one provided (if provided)
if($this->_output["country"] == "" && preg_match("/(". implode('|',$this->_countries) . ")/i", $this->_string)){
preg_match ("/(". implode('|',$this->_countries) . ")/i", $this->_string, $container["country"]);
$this->_output["country"] = $container["country"][0];
$this->_found[] = $this->_output['country'];
$this->remove($this->_output["country"]);
}
if(preg_match ("/([0-9]{1,})\s+([.\\-a-zA-Z\s*]{1,})/", $this->_string)){
preg_match ("/([0-9]{1,})\s+([.\\-a-zA-Z\s*]{1,})/", $this->_string, $container["address"]);
$this->_output["number"] = $container["address"][1];
$this->_output["street"] = $container["address"][2];
$this->_found[] = $this->_output["number"] . " ". $this->_output["street"];
$this->remove($this->_output["number"]);
$this->remove($this->_output["street"]);
}
//echo $this->_string;
}
/* remove from string in order to make it easier to find missing this */
protected function remove($string, $case_sensitive = false) {
$s = ($case_sensitive==false ? "i" : "");
$this->_string = preg_replace("/".$string."/$s", "", $this->_string);
}
public function getNotFound() {
return array_values(array_filter(array_diff($this->_sections, $this->_found)));
}
public function getFound() {
return $this->_found;
}
/* outputs a readable string with all items found */
public function toString() {
$output = $this->getOutput();
$string = "Original string: [ ".$this->_original_string.' ] ---- New string: [ '. $this->_string. ' ]<br>';
foreach($output as $type => $data) {
$string .= "-".$type . ": " . $data. '<br>';
}
return $string;
}
/* return the final output as an array */
public function getOutput() {
return $this->_output;
}
}
$array = array();
$array[0] = "123 Main Street, New Haven, CT 06518";
$array[1] = "123 Main Street, New Haven, CT";
$array[2] = "123 Main Street, New Haven, CT 06511";
$array[3] = "New Haven,CT 66554, United States";
$array[4] = "New Haven, CT06513";
$array[5] = "06513";
$array[6] = "123 Main Street, New Haven CT 06518, united states";
$array[7] = "1253 McGill College, Montreal, QC H3B 2Y5"; // google Montreal/Canada
$array[8] = "1600 Amphitheatre Parkway, Mountain View, CA 94043"; // google CA/US
$array[9] = "20 West Kinzie St., Chicago, IL 60654"; // google IL/US
$array[10] = "405 Rue Sainte-Catherine Est, Montreal, QC"; // Montreal address shows hyphened street names
$array[11] = "48 Pirrama Road, Pyrmont, NSW 2009"; // google Australia
foreach($array as $string) {
$a = new Extract($string);
echo $a->toString().'<br>';
}
:
Original string: [ 123 Main Street, New Haven, CT 06518 ] ---- New string: [ , , ]
-state: CT
-city: New Haven
-country: United States
-zip: 06518
-street: Main Street
-number: 123
Original string: [ 123 Main Street, New Haven, CT ] ---- New string: [ , , ]
-state: CT
-city: New Haven
-country:
-zip:
-street: Main Street
-number: 123
Original string: [ 123 Main Street, New Haven, CT 06511 ] ---- New string: [ , , ]
-state: CT
-city: New Haven
-country: United States
-zip: 06511
-street: Main Street
-number: 123
Original string: [ New Haven,CT 66554, United States ] ---- New string: [ , , ]
-state: CT
-city: New Haven
-country: United States
-zip: 66554
-street:
-number:
Original string: [ New Haven, CT06513 ] ---- New string: [ , ]
-state: CT
-city: New Haven
-country: United States
-zip: 06513
-street:
-number:
Original string: [ 06513 ] ---- New string: [ 06513 ]
-state:
-city:
-country:
-zip:
-street:
-number:
Original string: [ 123 Main Street, New Haven CT 06518, united states ] ---- New string: [ , , ]
-state: CT
-city: New Haven
-country: United States
-zip: 06518
-street: Main Street
-number: 123
Original string: [ 1253 McGill College, Montreal, QC H3B 2Y5 ] ---- New string: [ , , ]
-state: QC
-city: Montreal
-country: Canada
-zip: H3B 2Y5
-street: McGill College
-number: 1253
Original string: [ 1600 Amphitheatre Parkway, Mountain View, CA 94043 ] ---- New string: [ , , ]
-state: CA
-city: Mountain View
-country: United States
-zip: 94043
-street: Amphitheatre Parkway
-number: 1600
Original string: [ 20 West Kinzie St., Chicago, IL 60654 ] ---- New string: [ , , ]
-state: IL
-city: Chicago
-country: United States
-zip: 60654
-street: West Kinzie St.
-number: 20
Original string: [ 405 Rue Sainte-Catherine Est, Montreal, QC ] ---- New string: [ , , ]
-state: QC
-city: Montreal
-country:
-zip:
-street: Rue Sainte-Catherine Est
-number: 405
Original string: [ 48 Pirrama Road, Pyrmont, NSW 2009 ] ---- New string: [ , , ]
-state: NSW
-city: Pyrmont
-country: Australia
-zip: 2009
-street: Pirrama Road
-number: 48
당신이 사용할 수 있도록 실제 저장된 값을 추출 할 경우
.
getOutput()
으로 전화해야합니다. 그러면 필요한 모든 값을 가진 배열이 반환됩니다.
Array
(
[state] => CT
[city] => New Haven
[country] => United States
[zip] => 06518
[street] => Main Street
[number] => 123
)
이 클래스는 크게 최적화하고 개선 할 수 있음을 유의하시기 바랍니다 : 우리는이 방법을 사용하여 우리의 목록과 출력의 값을 첫 번째 주소를 취할 경우, 출력해야한다. 이것이 내가 한 시간 안에 생각해 낸 것이므로 모든 유형의 입력에 대해 작동 할 것이라고 보장 할 수는 없습니다. 본질적으로 사용자는 최소한 주소 부분을 구분하기 위해 쉼표를 사용하는 데 최소한의 노력을해야합니다. 또한 대문자 상태가 제공되고 유효한 5 자리 우편 번호인지 확인하려고합니다.
몇 가지 규칙 우편 번호를 추출하기 위해
- 는 유효한 2 문자 상태는 옆에 유효한 우편 번호를 제공해야합니다. 예 : CT 06510. 상태가 없으면 거리 번호에 5 자리 숫자가있을 수 있으므로 단순히 5 자리를 입력하는 것은 의미가 없습니다. (둘 사이를 구별 할 수 없다).
숫자와 단어가 순서대로 제공되는 경우에만 거리와 숫자를 추출 할 수 있습니다. 예 : 123 Main Street
. 또한 쉼표로 구분하거나 숫자 뒤에 나오는 모든 단어를 캡처합니다. 예를 들어, 123 Main Street New Haven, CT 06518
, 코드는 거리와 숫자가 123 Main Street
이 아닌 123 Main Street New Haven
이라는 코드를 사용합니다.
단순히 5 자리 우편 번호를 입력해도 작동하지 않습니다.
국가가 지정되지 않은 경우 올바른 우편 번호가있는 국가를 추측합니다 (위의 우편 번호 및 해당 국가 목록 참조).
하이픈이 제공되지 않는다고 가정합니다 (특히 도시 이름의 경우). 나중에 수정할 수 있습니다. (정규 표현식은 도시와 거리 이름 모두에 하이픈이있는 단어를 수용 할 수 있도록 수정해야합니다). (고정)
결론은 정규 표현식을 변경하고 수정하고 이에 맞게 사용자 정의 할 수있는 시간이 많으면 많은 일을 할 수 있다는 것입니다.
입력에 제공된 주소를 쉽게 캡처하기 위해 양식을 사용하도록 강력히 권합니다 (아직 가지고 있지 않은 경우). 아마 네 인생을 훨씬 편하게 해줄거야.
잘 형성 방법
$Extract = new Extract("123 Main Street, New Haven, CT 06518");
$foundValues = $Extract->getOutput();
가 입력이 보장되는 빠른 사용? 일반적으로 주소는 무엇이든 보장 할 수 없습니다. 사용자가 입력 한 주소 문자열은 무엇보다도 다양한 다양성과 엣지 케이스를 가지고 있습니다. 있는 그대로 전체 문자열을 가져 와서 지오 코딩 서비스로 보내고 개별 요소를 쉽게 추출 할 수있는 구조화 된 데이터를 가져 오는 것이 더 바람직 할 수 있습니다. – David
감사합니다. @David 입력 내용이 제 경우에 잘 형성됩니다. 그래서 완전히 개방 된 문제는 아닙니다. 그러나 지오 코딩 서비스에 대한 흥미로운 점을 제시합니다. – rogerb