Tôi đang tìm thư viện có chức năng tương tự với mô-đun Perl Lingua::EN::NameParse. Về cơ bản, tôi muốn phân tích các chuỗi như 'Mr. Bob R. Smith 'vào các thành phần tiền tố, tên, họ và tên hậu tố. Google đã không được giúp đỡ nhiều trong việc tìm kiếm một cái gì đó như thế này và tôi không muốn cuộn của riêng tôi nếu có thể. Bất cứ ai biết về một thư viện Java OSS có thể làm điều này một cách tinh vi?Thư viện phân tích cú pháp tên Java?
Trả lời
Cá nhân, tôi sẽ chọn tham gia regular expressions. Đây là một số intro tốt. Chúng nhanh chóng, súc tích và luôn luôn làm những gì bạn muốn.
Nếu bạn muốn ở trong ranh giới của sdk java, hãy sử dụng String tokenizers.
Thấp hơn một chút là JavaCC, trình tạo trình phân tích cú pháp dựa trên java. Đây là link to a tutorial.
Một giải pháp thay thế cho javaCC là ANTLR, cá nhân tôi đã có trải nghiệm tốt.
mã đơn giản này có thể giúp:
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;
}
}
Ví dụ đầu vào này:
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);
Có kết quả này:
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.]
Tôi chỉ không thể tin được một người nào đó chưa chia sẻ thư viện cho điều này - tôi cũng đã xem github và có một phân tích cú pháp tên javascript có thể được dễ dàng dịch sang java: https://github.com/joshfraser/JavaScript-Name-Parser
Tôi cũng sửa đổi mã trong một trong các câu trả lời để làm việc tốt hơn một chút và tôi đã bao gồm một trường hợp thử nghiệm:
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;
}
}
thử nghiệm trường hợp:
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());
}
}
}
Phương pháp này isOneOf nên được viết lại như sau: isOneOf boolean tin (String checkStr, String [] tiêu đề) { cho (Tiêu đề chuỗi: tiêu đề) nếu (checkStr.equalsIgnoreCase (tiêu đề)) trả về true; trả về false; } Bởi vì hiện tại, nó sẽ nhận ra tất cả các tên bắt đầu bằng V làm hậu tố. – KimvdLinde
Apache Commons có lớp HumanNameParser.
Name nextName = parser.parse("James C. ('Jimmy') O'Dell, Jr.")
String firstName = nextName.getFirstName();
String nickname = nextName.getNickName();
Bạn có thể tìm thấy nó trên [github] (https://github.com/apache/commons-text/blob/master/src/main/java/org/apache/commons/text/names/HumanNameParser.java).Phiên bản hiện tại vẫn là SNAPSHOT. –
- 1. Phương tiện phân tích cú pháp Thư viện C++
- 2. Thư viện C để phân tích cú pháp Ngày giờ
- 3. Thư viện phân tích cú pháp SQL cho Python
- 4. Đặc điểm tệp/thư viện phân tích cú pháp .blg
- 5. Thư viện trình phân tích cú pháp toán học Javascript
- 6. Trình phân tích cú pháp email Java?
- 7. Có ai biết thư viện trong Java có thể phân tích cú pháp ESRI Shapefile không?
- 8. Kết hợp phân tích cú pháp phân tích cú pháp, phân tích cú pháp và phân tích cú pháp rừng
- 9. Có thư viện Java nào để phân tích cú pháp các tệp PO gettext không?
- 10. Thư viện Java để phân tích cú pháp tham số dòng lệnh?
- 11. Có thư viện ngữ pháp phân tích cú pháp (PEG) nào cho Javascript hoặc PHP không?
- 12. Đọc và phân tích cú pháp KML trong java
- 13. Phân tích cú pháp các tệp nhị phân MIPS: có thư viện Python để phân tích cú pháp dữ liệu nhị phân không?
- 14. Phân tích cú pháp RDF n-triple Java
- 15. gcc để phân tích cú pháp mã
- 16. Phân tích cú pháp nguồn Java với Scala
- 17. Có thư viện phân tích cú pháp PDF miễn phí nào hoạt động trong Android không?
- 18. Thư viện phân tích cú pháp chứng chỉ Crypto/X509 cho Python
- 19. Trình phân tích cú pháp HTML
- 20. Cách phân tích cú pháp JSONArray trong Java với Json.simple?
- 21. Cách phân tích cú pháp cây thư mục trong python?
- 22. Phân tích cú pháp CSV nhanh
- 23. Trình phân tích cú pháp SVG Python
- 24. JAVA - Thư viện phân tích và đánh giá biểu thức
- 25. Mã phân tích cú pháp cho .NET
- 26. Cần trình phân tích cú pháp C++
- 27. Học phân tích cú pháp trong python
- 28. Phân tích cú pháp HTML với Erlang
- 29. Phân tích cú pháp khối CDATA XML
- 30. Chọn trình phân tích cú pháp Haskell
+1 bạn có thể chỉ cho tôi một ví dụ về cách phân tích tên sử dụng GATE –