Java如何与通配符搜索模式一起使用?

时间:2018-09-19 14:45:27

标签: java

我对Java有问题。有一个Web应用程序,它的搜索功能在后端与Javascript和Java一起运行。我们只允许配置Java源代码,而不能配置Javascript。

问题是有一个ArrayList<UserDTO>。每个UserDTO包含IdFirstNameLastNameemail。当我在搜索引擎中键入*时,将显示所有List的结果。问题出在电子邮件上。如果我搜索一个名字或姓氏,就没有问题。当我搜索一封电子邮件时,没有任何效果。只有在我搜索这样的内容时它才起作用:f.e.电子邮件是gchat@mail.com,如果我输入* gchat@mail *,我会找到它。如果我输入.,此后将无济于事。另外,如果我不键入*,则无任何效果。 f.e.如果我只这样输入电子邮件:gchat@mail,则无效。

此代码为:

public ResponseEntity<List<UserDTO>> search(@PathVariable("query") String query) {
        List<UserDTO> results = new ArrayList<>();

        if (query != null && !query.trim().isEmpty()) {
            for (UserDTO user : USERS) {
                String regExp = "^" + query.trim().replace("*", ".*") + "$";

                Pattern pattern = Pattern.compile(regExp, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
                Matcher firstnameMatcher = pattern.matcher(user.getFirstName());
                Matcher lastnameMatcher = pattern.matcher(user.getLastName());
                Matcher emailMatcher = pattern.matcher(user.getEmail());


                if (firstnameMatcher.matches() || lastnameMatcher.matches() || emailMatcher.matches()) {
                    results.add(user);
                }
            }
        }

列表是这样的:

private static final List<UserDTO> USERS = new ArrayList<>();

    static {
        USERS.add(new UserDTO("jpap", "John", "Papadopoulos", "jpap@mail.com", true, "EL", new HashSet<>()));
        USERS.add(new UserDTO("kpav", "Konstantinos", "Pavlopoulos", "kpav@mail.com", true, "EL", new HashSet<>()));
        USERS.add(new UserDTO("echar", "Eleni", "Charalampous", "echar@mail.com", true, "EL", new HashSet<>()));
        USERS.add(new UserDTO("gchat", "Georgia", "Chatzipavlou", "gchat@mail.com", true, "EL", new HashSet<>()));
        USERS.add(new UserDTO("avel", "Apostolos", "Velis", "avel@mail.com", true, "EL", new HashSet<>()));
        USERS.add(new UserDTO("sliol", "Sofia", "Lioliou", "sliol@mail.com", true, "EL", new HashSet<>()));
        USERS.add(new UserDTO("ipap", "Iordanis", "Papageorgiou", "ipap@mail.com", true, "EL", new HashSet<>()));
        USERS.add(new UserDTO("jter", "John", "Terzis", "jter@mail.com", true, "EL", new HashSet<>()));
        USERS.add(new UserDTO("mkar", "Maria", "Karatasou", "mkar@mail.com", true, "EL", new HashSet<>()));
        USERS.add(new UserDTO("gap", "George", "Apostolidis", "gap@mail.com", true, "EL", new HashSet<>()));
    }

请有人帮我吗?我尝试过这种不同的类型,但没有任何正常工作。

3 个答案:

答案 0 :(得分:0)

如果我正确理解您的问题,则为“。”。在正则表达式中用作通配符。尝试在之前添加/。类似于您用*替换*的方式。

答案 1 :(得分:0)

多个问题:

  1. 通过连接这样的用户输入,用户可以输入正则表达式,然后编译这些正则表达式并运行它们。这听起来不错,但请注意,构造正则表达式可能会或多或少地使服务器崩溃(占用大量CPU和RAM),因此您可能不希望这样做:您可以使用Pattern.quote解决此问题。这也解决了其他问题,由于字符串的其余部分,字符串中的。*并不意味着您认为的含义(例如,由于您位于可选组的中间,或者诸如此类的原因是用户放置了他们的查询中有一个问号)。如果希望允许用户输入regexp,请使用整个字符串,并通过尝试将''替换为'。'来避免混乱。如果您不想要,请引用输入。

  2. 您使用^作为前缀,使用$作为后缀,这意味着正则表达式必须与ENTIRE输入匹配,因此如果我搜索“ foo @ bar”,不能完全匹配“ foo@bar.com”,因此将无法正常运行。解决方案是在开头和结尾处在其中添加一个附加的。*。

两者结合:

StringBuilder regexp = new StringBuilder("^");
for (String elem : query.trim().split("\\*")) regexp.append(".*").append(Pattern.quote(elem));
regexp.append(".*$");
Pattern pattern = Pattern.compile(regexp.toString(), Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);

答案 2 :(得分:-3)

看起来您的问题不在模式中,而在Spring REST中。

有关详细信息,请参见https://www.baeldung.com/spring-mvc-pathvariable-dot