java - 正则表达式方法

标签 java regex

我正在尝试提出一个函数,为指定的字符串生成可能的数据库匹配,其中大多数这些指定的字符串不能轻易匹配,因为它们采用不同的命名形式,例如电影的首字母缩写词。数据库值在此阶段仅使用全名。到目前为止我想出的是一个函数,它产生一个模式,其中每个单词的首字母由 .* 分隔,来自数据库候选者:

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/

相关文章:

java - 使用正则表达式在单个字符后删除零

javascript - 在javascript中返回正则表达式字符串的一部分

c# - 使用正则表达式解析特定的 CSS

java - 普罗米修斯指标 - 未找到

java - JPA 和 InnoDB,以及 JSP/JSTL 问题

Java图像写入

regex - grep 和正则表达式 - 元/通配符

r - 如果模式来自向量,如何替换字符串?

java - JAXB 类型已定义

java - Libgdx:有没有一种简单的方法可以使文本在按钮上的每个轴上居中?