Poszukuję biblioteki podobnej funkcjonalnie do modułu Perl Lingua::EN::NameParse. Zasadniczo chciałbym przeanalizować ciągi takie jak "Mr. Bob R. Smith "na komponenty przyrostka, imienia, nazwiska i sufiksu nazwy. Google nie pomogło w znalezieniu czegoś takiego i wolałbym nie używać własnych, jeśli to możliwe. Ktoś wie o bibliotece Java OSS, która potrafi to zrobić w wyrafinowany sposób?Biblioteka analizy nazw Java?
Odpowiedz
Osobiście wybrałbym opcję regular expressions. Oto dobry intro. Są szybkie, zwięzłe i zawsze robią, co chcesz.
Jeśli chcesz pozostać w granicach java sdk, użyj String tokenizers.
Nieco niższy poziom to JavaCC, generator parsera oparty na języku Java. Oto link to a tutorial.
Alternatywą dla javaCC jest ANTLR, z którą osobiście miałem dobre doświadczenia.
Ten prosty kod może pomóc:
import java.util.ArrayList;
import java.util.List;
public class NamesConverter {
private List<String> titlesBefore = new ArrayList<>();
private List<String> titlesAfter = new ArrayList<>();
private String firstName = "";
private String lastName = "";
private List<String> middleNames = new ArrayList<>();
public NamesConverter(String name) {
String[] words = name.split(" ");
boolean isTitleAfter = false;
boolean isFirstName = false;
int length = words.length;
for (String word : words) {
if (word.charAt(word.length() - 1) == '.') {
if (isTitleAfter) {
titlesAfter.add(word);
} else {
titlesBefore.add(word);
}
} else {
isTitleAfter = true;
if (isFirstName == false) {
firstName = word;
isFirstName = true;
} else {
middleNames.add(word);
}
}
}
if (middleNames.size() > 0) {
lastName = middleNames.get(middleNames.size() - 1);
middleNames.remove(lastName);
}
}
public List<String> getTitlesBefore() {
return titlesBefore;
}
public List<String> getTitlesAfter() {
return titlesAfter;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public List<String> getMiddleNames() {
return middleNames;
}
@Override
public String toString() {
String text = "Titles before :" + titlesBefore.toString() + "\n"
+ "First name :" + firstName + "\n"
+ "Middle names :" + middleNames.toString() + "\n"
+ "Last name :" + lastName + "\n"
+ "Titles after :" + titlesAfter.toString() + "\n";
return text;
}
}
Na przykład wejście:
NamesConverter ns = new NamesConverter("Mr. Dr. Tom Jones");
NamesConverter ns1 = new NamesConverter("Ing. Tom Ridley Bridley Furthly Murthly Jones CsC.");
System.out.println(ns);
System.out.println(ns1);
Ma to wyjście:
Titles before :[Mr., Dr.]
First name :Tom
Middle names :[]
Last name :Jones
Titles after :[]
Titles before :[Ing.]
First name :Tom
Middle names :[Ridley, Bridley, Furthly, Murthly]
Last name :Jones
Titles after :[CsC.]
Po prostu nie mogę uwierzyć komuś nie udostępnił do tego biblioteki - dobrze zaglądałem github i tam javascript nazwa parser, który może być łatwo przetłumaczony na Java: https://github.com/joshfraser/JavaScript-Name-Parser
ja również zmodyfikowany kod w jednym z odpowiedziami do pracy trochę lepiej i obejmowały przypadek testowy:
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
public class NameParser {
private String firstName = "";
private String lastName = "";
private String middleName = "";
private List<String> middleNames = new ArrayList<String>();
private List<String> titlesBefore = new ArrayList<String>();
private List<String> titlesAfter = new ArrayList<String>();
private String[] prefixes = { "dr", "mr", "ms", "atty", "prof", "miss", "mrs" };
private String[] suffixes = { "jr", "sr", "ii", "iii", "iv", "v", "vi", "esq", "2nd", "3rd", "jd", "phd",
"md", "cpa" };
public NameParser() {
}
public NameParser(String name) {
parse(name);
}
private void reset() {
firstName = lastName = middleName = "";
middleNames = new ArrayList<String>();
titlesBefore = new ArrayList<String>();
titlesAfter = new ArrayList<String>();
}
private boolean isOneOf(String checkStr, String[] titles) {
for (String title : titles) {
if (checkStr.toLowerCase().startsWith(title))
return true;
}
return false;
}
public void parse(String name) {
if (StringUtils.isBlank(name))
return;
this.reset();
String[] words = name.split(" ");
boolean isFirstName = false;
for (String word : words) {
if (StringUtils.isBlank(word))
continue;
if (word.charAt(word.length() - 1) == '.') {
if (!isFirstName && !this.isOneOf(word, prefixes)) {
firstName = word;
isFirstName = true;
} else if (isFirstName) {
middleNames.add(word);
} else {
titlesBefore.add(word);
}
} else {
if (word.endsWith(","))
word = StringUtils.chop(word);
if (isFirstName == false) {
firstName = word;
isFirstName = true;
} else {
middleNames.add(word);
}
}
}
if (middleNames.size() > 0) {
boolean stop = false;
List<String> toRemove = new ArrayList<String>();
for (int i = middleNames.size() - 1; i >= 0 && !stop; i--) {
String str = middleNames.get(i);
if (this.isOneOf(str, suffixes)) {
titlesAfter.add(str);
} else {
lastName = str;
stop = true;
}
toRemove.add(str);
}
if (StringUtils.isBlank(lastName) && titlesAfter.size() > 0) {
lastName = titlesAfter.get(titlesAfter.size() - 1);
titlesAfter.remove(titlesAfter.size() - 1);
}
for (String s : toRemove) {
middleNames.remove(s);
}
}
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getMiddleName() {
if (StringUtils.isBlank(this.middleName)) {
for (String name : middleNames) {
middleName += (name + " ");
}
middleName = StringUtils.chop(middleName);
}
return middleName;
}
public List<String> getTitlesBefore() {
return titlesBefore;
}
public List<String> getTitlesAfter() {
return titlesAfter;
}
}
testową Sprawa:
import junit.framework.Assert;
import org.junit.Test;
public class NameParserTest {
private class TestData {
String name;
String firstName;
String lastName;
String middleName;
public TestData(String name, String firstName, String middleName, String lastName) {
super();
this.name = name;
this.firstName = firstName;
this.lastName = lastName;
this.middleName = middleName;
}
}
@Test
public void test() {
TestData td[] = { new TestData("Henry \"Hank\" J. Fasthoff IV", "Henry", "\"Hank\" J.", "Fasthoff"),
new TestData("April A. (Caminez) Bentley", "April", "A. (Caminez)", "Bentley"),
new TestData("fff lll", "fff", "", "lll"),
new TestData("fff mmmmm lll", "fff", "mmmmm", "lll"),
new TestData("fff mmm1 mm2 lll", "fff", "mmm1 mm2", "lll"),
new TestData("Mr. Dr. Tom Jones", "Tom", "", "Jones"),
new TestData("Robert P. Bethea Jr.", "Robert", "P.", "Bethea"),
new TestData("Charles P. Adams, Jr.", "Charles", "P.", "Adams"),
new TestData("B. Herbert Boatner, Jr.", "B.", "Herbert", "Boatner"),
new TestData("Bernard H. Booth IV", "Bernard", "H.", "Booth"),
new TestData("F. Laurens \"Larry\" Brock", "F.", "Laurens \"Larry\"", "Brock"),
new TestData("Chris A. D'Amour", "Chris", "A.", "D'Amour") };
NameParser bp = new NameParser();
for (int i = 0; i < td.length; i++) {
bp.parse(td[i].name);
Assert.assertEquals(td[i].firstName, bp.getFirstName());
Assert.assertEquals(td[i].lastName, bp.getLastName());
Assert.assertEquals(td[i].middleName, bp.getMiddleName());
}
}
}
Metoda isOneOf powinny być zapisane jako: prywatnej logiczną isOneOf (String checkStr, String [] tytułów) { for (tytuł ciągu: tytuły) if (checkStr.equ.IgnoreCase (title)) return true; return false; } Ponieważ obecnie rozpozna wszystkie nazwy zaczynające się od litery V jako sufiksu. – KimvdLinde
Apache Commons ma klasę HumanNameParser.
Name nextName = parser.parse("James C. ('Jimmy') O'Dell, Jr.")
String firstName = nextName.getFirstName();
String nickname = nextName.getNickName();
Można go znaleźć na [github] (https://github.com/apache/commons-text/blob/master/src/main/java/org/apache/commons/text/names/HumanNameParser.java).Obecna wersja nadal jest jednak SNAPSHOT. –
- 1. Biblioteka analizy równań C++
- 2. Biblioteka analizy SQL dla Pythona
- 3. Android: najlepsza biblioteka analizy XML?
- 4. Ustawianie przestrzeni nazw podczas analizy
- 5. Biblioteka analizatorów kanałów RSS w języku Java
- 6. Czy istnieje bezpłatna biblioteka do analizy morfologicznej języka niemieckiego?
- 7. Biblioteka obiektów Java graficzna biblioteka odwiedzin
- 8. Biblioteka SSH dla Java
- 9. Lekka biblioteka gniazd Java
- 10. Biblioteka wydajności czasu Java
- 11. Biblioteka graficzna Java
- 12. Czysta biblioteka java sqlite?
- 13. Biblioteka grafiki Java
- 14. Biblioteka USB Java
- 15. biblioteka wideo java p2p?
- 16. Biblioteka plot 3D Java?
- 17. Biblioteka Java BitTorrent
- 18. Biblioteka dostawcy OAuth (Java)
- 19. Apache Java XMLRPC biblioteka
- 20. Biblioteka WebP dla java?
- 21. Biblioteka w java
- 22. Java Pdf Biblioteka Diff
- 23. Biblioteka sprinterów CSS Java
- 24. Biblioteka dopasowania krzywej Java
- 25. Java nazw globalny dostęp
- 26. Kompilacja nazw zastrzeżonych Java
- 27. Biblioteka tłumaczeń w języku Java
- 28. Dobra biblioteka sterowania procesem Java
- 29. Biblioteka Java SSH dla Androida?
- 30. Programowa przeglądarka internetowa Biblioteka Java
+1 możesz pokazać mi przykład, jak analizować przy użyciu nazwy GATE –