I have an array manipulation/situation that I cannot figure out. In a nutshell:
Get a string such as:
$testString = 'John doe 123 Main st 77555';
I am trying to get things split up to be 3 main parts such as:
$fname = 'John';
$lname = 'doe';
$address = '123 Main st 77555';
Currently I am exploding the array as such:
$splitTestString = explode(" ", $testString");
which gives me the string inside an array.
I've tried a for loop to go through the exploded string:
for($i = 0; $i <= count($splitTestString); $i++) {
$fname = $splitTestString[0];
$lname = $splitTestString[1];
if(is_numeric($splitTestString[2])) { //take into account 2 last names
$newAddress = $splitTestString[2];
} else {
$lname .= ' '.$splitTestString[2];
}
}
But I am not sure how to get the address after the initial numbers all into its own variable. Another string example:
$testString = 'John doe smith 123 main st 77555';
$fname = 'John';
$lname = 'doe smith';
$newAddress = '123 main st 77555';
The user would be instructed to enter the information in the above format of first name, last name, address and zip code.
This is my first question out of all the searches I've done on here and please let me know if I've not followed the rules properly. I'm just at my wits end on this problem and cannot seem to find a solution to this situation. Thanks in advance!
You don't need to do everything in a single loop, you should come up with a process for populating the name variables until you hit a word that starts with a number (is this really a safe assumption though?), then simply join the remainder into the address.
If possible, you should go back to the drawing board and provide a way for the user to provide the information in separate fields.
$testString = 'John doe smith villalobos garcia navarro 123 Main st 77555';
$parts = explode(' ', $testString);
// Don't assume we will always have a first or last name, there could be only an address
$fname = '';
// Set up a buffer for the last name words
$lnameBuffer = [];
// Process input buffer until we hit a part that begins with a number
while(!is_numeric(substr($parts[0], 0, 1)))
{
// Shift the next word off of the buffer
$currPart = array_shift($parts);
/*
* If we don't have a first name yet, set it
* Otherwise, append the word to the last name buffer
*/
if(empty($fname))
{
$fname = $currPart;
}
else
{
$lnameBuffer[] = $currPart;
}
}
// Join the last name buffer to populate the $lname variable
$lname = implode(' ', $lnameBuffer);
// The rest of the input buffer contains the address
$newAddress = implode(' ', $parts);
echo 'fname: '.$fname.PHP_EOL;
echo 'lname: '.$lname.PHP_EOL;
echo 'newAddress: '.$newAddress.PHP_EOL;
You could however achieve this much more easily using regex.
$testString = 'John doe smith villalobos garcia navarro 123 Main st 77555';
preg_match('/([^\s]\S+)\s([^\d]*)(.*)/', $testString, $matches);
$fname = $matches[1];
$lname = $matches[2];
$newAddress = $matches[3];
echo 'fname: '.$fname.PHP_EOL;
echo 'lname: '.$lname.PHP_EOL;
echo 'newAddress: '.$newAddress.PHP_EOL;
If your string is always formatted like "firstname lastname everything else is the address" you can just pass explode a limit like so:
$str = 'John doe 123 Main st 77555';
$parts = explode(' ', $str, 3);
var_dump($parts);
//array(3) {
// [0]=>
// string(4) "John"
// [1]=>
// string(3) "doe"
// [2]=>
// string(17) "123 Main st 77555"
//}
If you need to split with a rule like 'the first time we see a number indicates the start of an address' you can just find that and split the string up like so:
$str = 'john doe smith 123 fake street paris france';
$matches = [];
preg_match('/[0-9]/', $str, $matches, PREG_OFFSET_CAPTURE);
$numberPosition = $matches[0][1]; // this is the first matching element, and its position
$left = trim(substr($str, 0, $numberPosition)); // left side of the found number
$right = trim(substr($str, $numberPosition)); // right side of the found number
var_dump([
$left, $right
]);
//array(2) {
// [0]=>
// string(20) "john doe smith"
// [1]=>
// string(26) "123 fake street paris france"
//}
Related
i have following code which capitalize First name & Last name, But some user have names like : "Malou van Mierlo" or "Malou de Mierlo" i dont want the "van" or "de" to be capital. How do i manage these exceptions? I think i can be solved if i just capitalize the last word in the last name. but how ?
add_filter('woocommerce_checkout_posted_data', 'mg_custom_woocommerce_checkout_posted_data');
function mg_custom_woocommerce_checkout_posted_data($data){
// The data posted by the user comes from the $data param.
// You would look for the fields being posted,
// like "billing_first_name" and "billing_last_name"
if($data['billing_first_name']){
/*
From jAnE to Jane
*/
$data['billing_first_name'] = strtolower($data['billing_first_name']);
$data['billing_first_name'] = ucwords($data['billing_first_name']);
}
if($data['billing_last_name']){
/*
From DOe to Doe
*/
$data['billing_last_name'] = strtolower($data['billing_last_name']);
$data['billing_last_name'] = ucwords($data['billing_last_name']);
}
return $data;
}
You can do it by splitting the string and capitalizing first and last words of the string.
With this code you split the string:
$words = preg_split('/\s+/', $string);
array_map(strtolower, $words); // From jAnE to jane
With this code you capitalize the first and the last words of the name, and return the result:
$words[0] = ucfirst($words[0]);
$words[count($words) - 1] = ucfirst($words[count($words) - 1]);
return implode(' ', $words);
Try this
$a = explode(' ', 'MaLou van mIerlo');
$a[array_key_first($a)] = ucfirst(strtolower($a[array_key_first($a)]));
$a[array_key_last($a)] = ucfirst(strtolower($a[array_key_last($a)]));
$a = implode(' ', $a);
I have a string like the one below. I want to be able to extract the data and put it into variables. I would have used a function that focuses on a specifically formatted string but then it would create problems if the string is slightly different.
$str ="Surname : Lorem Creme
Name : Doe
Bank name :P.O.S
Account no:50345343
EC no:0000000K
ID no :85-000000 Q 85
DOB : 01-06-34
Employer name:min of education
Employeer Number: Borera pry 066 Mutawatawa
Client Physical Address: 45 New Lipore";
function ge($string, $start, $end){
$string = ' '. $string;
$ini =strpos($string, $start);
if ($ini == 0) return '';
$ini += strlen($start);
$len = strpos($string, $end, $ini) - $ini;
$den =substr($string, $ini, $len);
return substr($den, 0, -4);
}
if (isset($_POST['insert'])){
$real = $str;
$guru = preg_replace('/\s+/', '', $real);
$rem = str_replace(':', '', $guru);
$ren = str_replace('-', '', $rem);
$surname = ge($ren, "Surname", "Name");
$firstname =ge($ren, "Name", "Bankname");
$account_number = ge($ren, "Accountno", "ECno");
$Ec = ge($ren, "ECno", "IDno");
$id_num = ge($ren, 'IDno', "DOB");
$dob = ge($ren, "DOB", "Employername");
// Employer name:min of education
echo "First name: $firstname <br> Last name: $surname <br>";
echo "Bank : $bank_name <br>";
echo "ID Number : $id_num <br>";
echo "Account Number : $account_number <br>";
echo "DOB : $dob <br>";
echo "EC Number : $nex_ofk";
}
`
You can either you explode() twice with new line and then with : or you simple regex with preg_match_all
$str ="Surname : Lorem Creme
Name : Doe
Bank name :P.O.S
Account no:50345343
EC no:0000000K
ID no :85-000000 Q 85
DOB : 01-06-34
Employer name:min of education
Employeer Number: Borera pry 066 Mutawatawa
Client Physical Address: 45 New Lipore";
preg_match_all("#^\s*(.*?):\s*(.*?)\s*$#mx", $str, $matches);
var_dump(array_combine($matches[1], $matches[2]));
Output:
array(10) {
["Surname "]=>
string(11) "Lorem Creme"
["Name "]=>
string(3) "Doe"
["Bank name "]=>
string(5) "P.O.S"
["Account no"]=>
string(8) "50345343"
["EC no"]=>
string(8) "0000000K"
["ID no "]=>
string(14) "85-000000 Q 85"
["DOB "]=>
string(8) "01-06-34"
["Employer name"]=>
string(16) "min of education"
["Employeer Number"]=>
string(25) "Borera pry 066 Mutawatawa"
["Client Physical Address"]=>
string(13) "45 New Lipore"
}
The magic is in regex #^\s*(.*?):\s*(.*?)\s*$#mx you can find explanation here
array_combine() gets the values from 2 groups and combine them together to get one array.
preg_match_all applies regex to given string and return the output in
$matches array
Simplest way is with two explode calls:
<?php
$str ="Surname : Lorem Creme
Name : Doe
Bank name :P.O.S
Account no:50345343
EC no:0000000K
ID no :85-000000 Q 85
DOB : 01-06-34
Employer name:min of education
Employeer Number: Borera pry 066 Mutawatawa
Client Physical Address: 45 New Lipore";
//Split string into separate lines
$lines = explode(PHP_EOL, $str);
$result = array();
foreach($lines as $ln){
//Use explode to get the pieces left and right of the ':'
list($key, $val) = explode(':', $ln);
//Put that in a new array; use trim to get rid of 'presumably' unwanted whitespace
$result[trim($key)] = trim($val);
}
var_dump($result);
?>
You can also do this in one line with a regular expression, but this is probably simpler to understand.
Use php explode() function:
http://php.net/manual/en/function.explode.php
First do explode by new row to get rows (check on PHP_EOL constant here: http://php.net/manual/en/reserved.constants.php) and loop through them.
Then use another explode() call to explode by ":" sign to get field name and field value.
Use trim() function to remove space characters if they bother you.
$rows = explode(PHP_EOL, $str);
foreach ($rows as $row){
$rowParts = explode(':', $row);
$fieldName = trim($rowParts[0]);
$fieldValue = trim($rowParts[1]);
}
Should be something like that (I didn't test the code).
Depending on what your delimiter is, you can use explode()
In this case it looks like your delimiter is "\r\n". The explode would look like this:
$result = explode("\r\n", $str);
Afterwards you can explode on ":" as well, to get at key value result
I am dealing with dynamic user input, that can contain more than one space. What I am actually want to process is user's name. For examples: John John Doe, John Doe Michael, John Doe Michael Moore.
I have 2 variables. The first variable is for first name, so I just name it $fname and the second variable is for last name, let's name it $lname.
I want to put any string without space or any part of string before the first space to variable for first name or $fname and any part after the first space to the last name variable or $lname without removing the space between them.
So, if a user give names like John Doe Michael Moore, then I want to put John into the variable $fname and Doe Michael Moore into the variable $lname.
Here is my current approach:
$name = ( $_POST['name'] );
if(strpos($name, " ")) {
$name = explode(' ', $name);
$count = count($name);
$fname = '';
$lname = '';
for($i = 0; $i < $count; $i++) {
if($i == 0) {
$fname .= $name[$i];
} elseif($i == 1) {
$lname .= $name[$i];
} else {
$lname .= ' ' . $name[$i];
}
}
}
But I don't like to use loop in this situation. Is there any solution like using regex or something else?
There's no need for regular expressions; if you're pretty certain you will receive at least two names, you can keep the explode() as you have it:
list($fname, $lname) = explode(' ', $name, 2);
The third argument to explode() will limit the result to at most two elements. The list() performs the assignment to your two variables.
get it from the 2 matched groups.
^(\w+)\s+(.*)$
Online demo
Sample code:
$re = "/^(\\w+)\\s+(.*)$/";
$str = "John Doe Michael Moore";
preg_match_all($re, $str, $matches);
output:
1. [0-4] `John`
2. [5-22] `Doe Michael Moore`
Then just use explode but limit the array to two items like this:
// Set test data array.
$test_name_array = array('John', 'John Doe', 'John Doe Michael', 'John Doe Michael Moore');
// Roll through the test data array.
foreach ($test_name_array as $name) {
// Break the array into two parts.
$name = explode(' ', $name, 2);
$fname = isset($name[0]) && !empty($name[0]) ? $name[0] : '';
$lname = isset($name[1]) && !empty($name[1]) ? $name[1] : '';
// Check the output of `$name` for debugging.
echo '<pre>';
print_r($name);
echo '</pre>';
// Echo the first name.
echo 'First Name: ' . $fname;
echo '<br />';
// Echo the last name.
echo 'Last Name: ' . $lname;
echo '<br />';
}
And the output of that would be:
Array
(
[0] => John
)
First Name: John
Last Name:
Array
(
[0] =>
[1] => John Doe
)
First Name:
Last Name: John Doe
Array
(
[0] => John
[1] => Doe Michael
)
First Name: John
Last Name: Doe Michael
Array
(
[0] => John
[1] => Doe Michael Moore
)
First Name: John
Last Name: Doe Michael Moore
RegEx for first name:
^.*(?=[^ ]*)$
RegEx for last name:
[^ ]*$
Use this if you're certain that no last name in this world would ever include a whitespace character, which is not true. What is stopping you from giving the user the chance to tell you what's their actual first and what's their last name? I think this lack of UI/API functionality is the actual problem here.
I have an array which contains the full name. I know how to display the last name which basically resides in the 1st index. How can I display the rest of the values after the last name?
$fullname = array('fullname' => 'POTTER Harry James');
$res = implode("", $fullname);
$name = preg_split("/[\s,]+/", $res);
$lname = $name[0];
What i did in the first name:
$fname = $name[1]. " ".$name[2];
It works fine, but is there a cleaner way to do that? I mean, what if the user has more than 2 first names?
Thanks.
I suggest to use explode() function:
<?php
$fullname = array('fullname' => 'POTTER Harry James');
$parts = explode(' ', $fullname['fullname']);
var_dump($parts);
?>
Shows:
array(3) {
[0]=>
string(6) "POTTER"
[1]=>
string(5) "Harry"
[2]=>
string(5) "James"
}
You might use any part of $parts in a way, that you need.
<?php
$a = array_shift($parts);
$b = implode(' ', $parts);
echo "{$b} ({$a})"; // Harry James (POTTER)
?>
UPDv1:
In your current code, you might do just the same thing:
<?php
$lname = array_shift($name);
$fname = implode(' ', $name);
?>
I think you should take out the last name off the array first, then use a loop to concatenate the remaining names as fistname.
$fullname = array('fullname' => 'POTTER Harry James');
$res = implode("", $fullname);
$name = preg_split("/[\s,]+/", $res);
$lname = array_shift($name);
$fname = "";
foreach($name as $fnames)
$fname.= " ".$fnames;
$fullname = array('fullname' => 'POTTER Harry James');
$firstNames = strstr($fullname['fullname'], ' '); // $firstNames='Harry James'
This gets the string after the first space character.
This is a bit of an impossible task. If left to their own devices, users are going to put all sorts of stuff into a single field.
If you care about separating the first and last names of your users, you should ask for them separately, as there is no regex that can possibly determine the correct way to break up their name.
You could do
<?php
$fullname = array('fullname' => 'POTTER Harry James');
list($lname,$fname) = explode(" ", $fullname["fullname"],2);
echo $fname."<br>".$lname;
?>
This will work if the name contains 2 words or more. In case there are more than 2 words then anything except the first word will be considered as first name and first word will be considered as the last name.
I'm having some trouble parsing a first name and last name from a string into 2 different variables.
The string is always in this format: "Smith, John" or "Doe, Jane"
Is there a function out that can split the first and last name to 2 different variables to something like...
$firstname = "John"
$lastname = "Smith"
Use list with explode like this:
list($firstname, $lastname) = explode(',', $yourString);
You may need to use trim to remove any whitespace from those vars.
explode() splits a string based upon another string and returns an array.
You could do:
$name = "Smith, John";
$name_array = array();
$name_array = explode(",", $name);
I would go with regexp for this so that there could be slight variations in the input (i.e. "Smith, John", "Smith ,John", "Smith , John" or "Smith,John")
You could do something like this for regexp "\w([a-z]+)\w" and then last name would be your first match and first name would be your second match.
$name = "Smith, John";
$expl = explode(', ', $name);
$firstname = $expl[1];
$lastname = $expl[0];
echo $firstname.' '.$lastname;