我正在尝试提出一个函数,为指定的字符串生成可能的数据库匹配,其中大多数这些指定的字符串不能轻易匹配,因为它们采用不同的命名形式,例如电影的首字母缩写词。数据库值在此阶段仅使用全名。到目前为止我想出的是一个函数,它产生一个模式,其中每个单词的首字母由 .* 分隔,来自数据库候选者:
pkgName matched: The.Fighter.2010.DVDRip.XviD.AC3-TiMPE, for pattern: .*0.*M.*, title: 007 Moonraker pkgName matched: The.Fighter.2010.DVDRip.XviD.AC3-TiMPE, for pattern: .*1.*A.*M.*, title: 12 Angry Men pkgName matched: The.Fighter.2010.DVDRip.XviD.AC3-TiMPE, for pattern: .*3.*, title: 300 pkgName matched: The.Fighter.2010.DVDRip.XviD.AC3-TiMPE, for pattern: .*A.*P.*, title: A Prophet pkgName matched: The.Fighter.2010.DVDRip.XviD.AC3-TiMPE, for pattern: .*A.*, title: Adaptation pkgName matched: The.Fighter.2010.DVDRip.XviD.AC3-TiMPE, for pattern: .*A.*, title: Adventureland pkgName matched: The.Fighter.2010.DVDRip.XviD.AC3-TiMPE, for pattern: .*A.*, title: Amelie pkgName matched: The.Fighter.2010.DVDRip.XviD.AC3-TiMPE, for pattern: .*A.*P.*, title: American Psycho
The problem is this method is producing too many unwanted suggested matches (all unwanted in my previous example). Can anyone suggest a better method that would trim down unwanted these matches? Are regular expressions even suitable for this?
public ArrayList<Movie> databaseMatches(String pkgName) {
Connection conn = getConnection();
ArrayList<Movie> dbMatches = new ArrayList<Movie>();
try {
for (Movie dbTitle : getDatabaseMovies(conn)) {
Pattern p = Pattern.compile(createTitlePattern(dbTitle.getTitle()));
Matcher m = p.matcher(pkgName);
if (m.find()) {
System.out.println("pkgName matched: " + pkgName + ", for pattern: " + createTitlePattern(dbTitle.getTitle()) + ", title: " + dbTitle.getTitle());
dbMatches.add(dbTitle);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return dbMatches;
}
private String createTitlePattern(String dbTitle) {
// System.out.println("dbTitle: " + dbTitle + "split(' ')");
String titleParts[] = dbTitle.split(" ");
String searchPattern = ".*";
for (int i = 0; i < titleParts.length; i++) {
char c = titleParts[i].charAt(0);
searchPattern += (c + ".*");
}
// System.out.println("pattern produced: " + searchPattern);
return searchPattern;
}
编辑:我遇到过在每个首字母缩写词之间包含各种字符的字符串实例,所以我认为这种模式是合适的。
最佳答案
由于您对数据格式的标准太少,因此您可能需要使用略有不同的方法,这可能可行也可能不可行,具体取决于您的数据大小/应用程序的吞吐量需求。一个建议是从全文匹配开始,只有当无法产生结果时才转向更通用的搜索或其他变体。
对于前面的示例,您可以从完整的关键字搜索开始:
.*American.*Psycho.*
如果无法产生结果,请尝试纯首字母缩略词搜索
.*AP.*
如果单个关键字搜索失败
.*((American)|(Psycho)).*
然后进行混合关键字/缩写搜索
.*(A|(American)).*(P|(Psycho))
等同样,根据搜索运行的速度/您需要它们运行的速度,这种方法可能会受到很大阻碍。
如果这是 Not Acceptable ,您可以尝试使用如上所述的单个“松散”模式,并在可能的情况下尝试允许完整的单词匹配,并尽量减少关键字之间的分组。
.*(A[merican]*)(.*?)(P[sycho]*)
请注意,我们使用字符类(方括号)而不是常规分组(圆括号)来允许对剩余标题进行部分匹配。即前一个匹配“Amer. Psy.”。然后根据您获得的匹配项,您可以进一步检查分组以消除误报。例如,如果第 1 组仅匹配“A”,您可能认为第 2 组为空,或仅包含非字母数字,如果不是,您会将其作为误报拒绝。
关于java - 正则表达式方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4969933/