Regex - Dönüş Adı ve Soyadı

6 Cevap php

I return the first and last name of a person given the full name, şimdiye kadar düşünebildiğim en iyi aşağıdaki normal ifade için en iyi güvenilir yol arıyorum:

$name = preg_replace('~\b(\p{L}+)\b.+\b(\p{L}+)\b~i', '$1 $2', $name);

Beklenen çıkışı böyle bir şey olmalı:

William -> William // Regex Fails
William Henry -> William Henry
William Henry Gates -> William Gates

Ben de support accents, örneğin "João" bunu istiyorum.

EDIT: I understand that some isimleri doğru tespit olmayacaktır, ama bu son söz soyadı (bütün soyadı olmayabilir nerede bir yerel sitede kullanılan olacak çünkü bu, benim için bir sorun değil Ben istediğim "Sevgili FIRST_NAME LAST_NAME" tamamen geçerli, benim için işe yaramaz ise, Peki tüm bu tartışma ... söylemek için hızlı bir yoldur çünkü gerçi) ama bu bir sorun değildir.

Birisi bu konuda bana yardımcı olabilir?

6 Cevap

Olduğu gibi, bir soyadı gerektiren konum - ki, elbette, ilk örnek yoktur.

Kümelenmiş gruplama, (?:...) kullanın ve 0-veya-1 sayısı, ?, orta ve onlara bağlı olmasını sağlamak için bir bütün olarak son isimler için:

'~\b(\p{L}+)\b (?: .+\b(\p{L}+)\b )?~ix'  # x for spacing

Bu ilk isim son / orta isimleri verilmiş olup olmadıklarını çekilecek izin vermelidir.

$name = preg_replace('~\b(\p{L}+)\b(?:.+\b(\p{L}+)\b)?~i', '$1 $2', $name);

Bu duymak istediklerini olmayabilir, ama ben isimleri düzenli değil çünkü bu sorun bir düzenli ifade için uygun olduğunu düşünmüyorum. Ben bile bağlam-duyarlı veya bağlam-özgür olduğunu sanmıyorum. Eğer bir şey, onlar ve düzenli ifade motoru sınırsız bir dilbilgisi ayrıştırmak (ben oturup yaptım daha fazla aracılığıyla Emin, ama söylemek önce düşünmek gerekir) sınırsız vardır.

Yerine regex size daha kolay gibi bir şey yapmak bulabilirsiniz:

$parts = explode(" ", $name);
$first = $parts[0];
$last = ""
if (count($parts) > 1) {
    $last = $parts[count($parts) - 1];
}

Önce tek bir alan boşluklarla birden fazla ardışık bit değiştirmek isteyebilirsiniz, bu nedenle boş bit alamadım, ve sondaki / önde gelen boşluklarla kurtulmak:

$name = ereg_replace("[ \t\r\n]+", " ", trim($name));

Depending on how clean your data is, I think you are going to have a tough time finding a single regex that does what you want. What different formats do you expect the names to be in? I've had to write similar code and there can be a lot of variations: - first last - last, first - first middle last - last, first middle

Ve sonra eklerin (vb Küçük, üst düzey III) ve önek (Bay, Bayan, vb) gibi şeyler, kombine adları (örneğin, John ve Mary Smith) var. Bazıları zaten söylediğim gibi, aynı zamanda da çok parçalı son adları (örneğin Victor de la Hoya) ile uğraşmak zorunda.

Ben güvenilir ilk ve son adları çekin edemeden bu olasılıklara tüm uğraşmak zorunda bulundu.

Eğer ilk uzay önce ve son boşluktan sonra metin olarak ilk ve son adı tanımlama ediyorsanız, o zaman sadece uzaylarda dize bölmek ve dizinin ilk ve son elemanları kapmak.

Tüm dünyada adları bu desen karşılamak değil - Ancak, ne yaptığınızı bağlam / kapsamına bağlı olarak, yeniden değerlendirmek şeyler gerekebilir.

Ben senin en iyi seçenek, sadece soyadı ie olarak ilk isimden sonra her şeyi tedavi için olduğunu düşünüyorum

William Henry Gates
Forename: William
Surname: Henry Gates

Değil herkes gibi onun güvenli mekanizma zaten onların göbek adı girecektir. Sadece William ayıklamak değil - Henry görmezden - ve tüm bilirsin gibi Gates'i ayıklamak, Henry Soyadı parçasıdır.