How can I separate firstname and surname from a string like this:
Pietro DE GIOVANNI
(Pietro being the firstname and DE GIOVANNI the surname)
I used to do it with an explode() on the spaces, but obviously it doesn't work on a person like that.
Thanks in advance.
You can explode on the names by spaces as before, then loop the result as individual pieces of the name. Check with ctype_upper() if the string is purely uppercase or not, and append it to the proper variable.
Putting it into a function, it may look like this
function split_name($fullname) {
$firstname = "";
$surname = "";
$pieces = explode(" ", $fullname);
foreach ($pieces as $name) {
if (ctype_upper($name))
$surname .= $name." ";
else
$firstname .= $name. " ";
}
return array("firstname" => $firstname, "surname" => $surname);
}
You can then use it as such
$name = "Pietro DE GIOVANNI";
$split = split_name($name);
echo "Firstname: ".$split['firstname']."\nSurname: ".$split['surname'];
Note
This doesn't work for names such as James O'RILEY, John-Paul JOHNSON or John. F. KENNEDY. The first two we can circumvent by stripping away any characters that's not a-zA-Z before comparing with ctype_upper(), but the latter we won't be able to distinguish if it's a firstname or surname - there's not enough data to say either way. You can assume that it's always a part of the firstname (for instance), and/or check if it's after we've started looking at the surnames (if a name in capital letters has been found yet). You can take care of the first two cases by checking for
if (ctype_upper(filter_var(str_replace("'", "", $name), FILTER_SANITIZE_STRING)))
instead of using the if statement in the original codeblock. This removes quotes and any non-a-zA-Z values.
Here's a live demo where I've stripped away names that contain any characters beside a-zA-Z, which would account for the two first issues.
Related
Here i want to validate a name where:
A name only consist of these characters [a-zA-Z-'\s]
however a sequence of two or more of the hyphens or apostrophe can not exist
also a name should start with a letter.
I tried
$name = preg_match("/^[a-zA-Z][a-zA-Z'\s-]{1,20}$/", $name);
however it allows double hyphens and apostrophes.
If you can help thank you
You can invalidate names containing a sequence of two or more of the characters hyphen and apostrophe by using a negative lookahead:
(?!.*['-]{2})
For example
$names = array('Mike Cannon-Brookes', "Bill O'Hara-Jones", "Jane O'-Reilly", "Mary Smythe-'Fawkes");
foreach ($names as $name) {
$name_valid = preg_match("/^(?!.*['-]{2})[a-zA-Z][a-zA-Z'\s-]{1,20}$/", $name);
echo "$name is " . (($name_valid) ? "valid" : "not valid") . "\n";
}
Output:
Mike Cannon-Brookes is valid
Bill O'Hara-Jones is valid
Jane O'-Reilly is not valid
Mary Smythe-'Fawkes is not valid
Demo on 3v4l.org
I am trying to find the last name from full names with trailing credentials. Some names have middle names or initials, hyphenated names, multiple credentials, and some have no trailing credentials:
John Doe, MD
Jane X. Doe, FNP-C
Joe Cool, MD, PhD
Billie-Jo Last
I've started with
/\w+(?=[\s,]+\S*$)/gmi
which gets the last names of the first 2 formattings, but picks up the 1st credential and first name of the second 2 formattings, respectively.
Thank you for all your help.
If you are 100% confident that they all follow the format you posted, you can do this per row (per person):
// Get the names part of the string
$parts = exlode(',', $nameString);
// The first element is the names.
// Now, split the name string to get the names
$names = explode(' ', $parts[0]);
$first = $names[0];
$middle = null;
$last = null;
if (count($names) == 2) {
// We only have two names, which probably means that
// the second is the last name
$last = $names[1];
}
if (count($names) == 3) {
// We got three names, let's assume that the second is the middle name
$middle = $names[1];
// And the third is the last name
$last = $names[2];
}
The above code can be optimized, but I wanted to make it as self explanatory as possible.
Note: This only works for the names that follows the format you mentioned. If you were to get more than three names, you have a problem since you won't be able to determine if it is a double first, middle or last name.
If all your input is well structured as you described, then the best advice is to do what #Magnus Eriksson stated in his commend. The code is extremely simple:
$parts = explode(',', $inputString);
$names = explode(' ', trim($parts[0]));
$lastName = $names[count($names) - 1];
I'd like to know How to Search for Space in Php
For example , I've got $Studentname and it's value is John Green . I want to have $Name (with value John) And $Surname(With value Green) . But i don't know how to search space in string .
Thanks in advance
Using explode() without a limit will result in incorrect results. Some first and last names have spaces. For example:
$name = explode(" ","Jan Van Riebeck");
echo $name[0]." ".$name[1]; // Jan Van (incorrect)
$name = explode(" ","St. John Westcox");
echo $name[0]." ".$name[1]; // St. John (incorrect)
Use explode() with a limit (so it only returns 2 items), like so:
$name = explode(" ","Jan Van Riebeck",2);
echo $name[0]." ".$name[1]; // Jan Van Riebeck (correct)
This will still be incorrect some time, but more last names have spaces than first names. Ideally, if you're capturing the form data, use two different fields for first and last name, but even this isn't always ideal, some cultures have different ways that names work that aren't as simple as first name last name.
Here is a list of common pitfalls when it comes to working with names
First suggestion:-
Try to take first name and last name in two different fields when you are using html form.
Use below code if the above not possible:-
<?php
$Studentname = 'John Green';
$student_full_name = explode(' ',trim($Studentname));//trim to remove space from starting and ending and explode to break string when space found
$first_name = $student_full_name[0];//output John
$sur_name = $student_full_name[1];//output Green
?>
Note:- What happen if a user put name like "John Green smith" Or "John(more than one space)Green". That's why do first point.
You can use the explode() function to split a string into an array by using the space as a delimiter:
$names = explode(" ", "John Smith");
However, you might want to take account of people doing silly things like putting double spaces between the first name and last name, or having preceding or trailing spaces.
You can use trim() for getting rid of trailing and preceding spaces:
$fullName = " John Smith ";
$trimmedName = trim($fullName); // Assigns "John Smith"
You can also use preg_replace() to get rid of multiple spaces between the first and last name:
$fullName = "John Smith";
$cleanedName = preg_replace("/\s+/", " ", $fullName); // Assigns "John Smith"
The above code will replace one or more (+) consecutive spaces (\s) with a single space.
to get name and username from student name follow this
$Studentname = 'John Green';
$name = explode(' ',$Studentname);
$firstname = $name[0]; //output john
$lastname = $name[1]; //output green
I am having a problem with regular expressions at the moment.
What I'm trying to do is that for each line through the iteration, it checks for this type of pattern: Lastname, Firstname
If it finds the name, then it will take the first letter of the first name, and the first six letters of the lastname and form it as an email.
I have the following:
$checklast = "[A-z],";
$checkfirst = "[A-z]";
if (ereg($checklast, $parts[1])||ereg($checkfirst, $parts[2])){
$first = preg_replace($checkfirst, $checkfirst{1,1}, $parts[2]);
print "<a href='mailto:$first.$last#email.com;'> $parts[$i] </a>";
}
This one obviously broke the code. But I was initially attempting to find only the first letter of the firstname and then after that the first six letters of the lastname followed by the #email.com This didn't work out too well. I'm not sure what to do at this point.
Any help is much appreciated.
How about something like this:
$name = 'Smith, John';
$email = preg_replace('/([a-z]{1,6})[a-z]*?,[\\s]([a-z])[a-z]*/i',
'\\2.\\1#email.com', $name);
echo $email; // J.Smith#email.com
Cheers
I've created a regular expression in C# but now I'm struggling when trying to run it in PHP. I presumed they'd work the same but obviously not. Does anyone know what needs to be changed below to get it working?
The idea is to make sure that the string is in the format "Firstname Lastname (Company Name)" and then to extract the various parts of the string.
C# code:
string patternName = #"(\w+\s*)(\w+\s+)+";
string patternCompany = #"\((.+\s*)+\)";
string data = "Firstname Lastname (Company Name)";
Match name = Regex.Match(data, patternName);
Match company = Regex.Match(data, patternCompany);
Console.WriteLine(name.ToString());
Console.WriteLine(company.ToString());
Console.ReadLine();
PHP code (not working as expected):
$patternName = "/(\w+\s*)(\w+\s+)+/";
$patternCompany = "/\((.+\s*)+\)/";
$str = "Firstname Lastname (Company Name)";
preg_match($patternName, $str, $nameMatches);
preg_match($patternCompany, $str, $companyMatches);
print_r($nameMatches);
print_r($companyMatches);
Seems to work here. What you should realize is that when you're capturing matches in a regex, the array PHP produces will contain both the full string that got matched the pattern as a whole, plus each individual capture group.
For your name/company name, you'd need to use
$nameMatches[1] -> Firstname
$nameMatches[2] -> Lastname
and
$companyMatches[1] -> Company Name
which is what got matched by the capture group. the [0] element of both is the entire string.
It could be because you're using double-quotes. PHP might be intercepting your escape sequences and removing them since they are not recognized.
Your patterns do appear to extract the information you want. Try replacing the two print_r() lines with:
print "Firstname: " . $nameMatches[1] . "\n";
print "Lastname: " . $nameMatches[2] . "\n";
print "Company Name: " . $companyMatches[1] . "\n";
Is there anything wrong with this output?
Firstname: Firstname
Lastname: Lastname
Company Name: Company Name