Shaik Md
Shaik Md

Reputation: 601

String matches does not work for special char "/"

I have a requirement wherein I need to match and list a few objects based on the data provided in the filter.
The user might also enter a regex for the match.

For example:
As list of Strings I have: "test","detest","test0/1/1"

Filter 1:
"te" ---> prints all the elements in the list

Filter 2:
"te*" --- > Prints only "test","detest" and not the third element.

I want to match the char "/" as well

I want the below filters also to give me a matched result:

te*0/*

*st*

Code-snippet of what I've tried so far:

import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class StringMatch {

    static List<String> values = Arrays.asList("test","detest","test0/1/1");

    public static Collection<String> query(String queryStr, List<String> values) {
        String orgQueryStr = queryStr;
        queryStr = queryStr.replaceAll("\\*", "\\\\w*");
        queryStr = "\\w*" + queryStr + "\\w*"; 
        System.out.println(queryStr);
        List<String> list = new ArrayList<String>();
        for (int i = 0; i < values.size(); i++) {
            String str = values.get(i);
            String str1 = str.toLowerCase();
            //System.out.println("Search string : " + str1 + " QueryString : " + queryStr + " Original : " + orgQueryStr);
            if (str1.matches(queryStr) || str1.contains(orgQueryStr)){
                //System.out.println("Matched !!");
                list.add(str);
            }  
            else{
                //System.out.println("Did not match " + str1);
            }
        }
        if (list.isEmpty())
            return null;
        else
            return list;
    }

    public static void main(String[] args) {
        String queryStr = "te*";
        System.out.println(URLDecoder.decode(queryStr));
        queryStr = URLDecoder.decode(queryStr);
        System.out.println(query(queryStr.toLowerCase(), values));
    }
}

Upvotes: 2

Views: 126

Answers (3)

Shaik Md
Shaik Md

Reputation: 601

Exact alphabetic order match will work with following two lines

    queryStr= queryStr.replaceAll("\\*+", ".*");
    queryStr = (queryStr.startsWith(".*") ? ".*" : "") + queryStr + (queryStr.endsWith(".*") ? "" : ".*"); 

Also this line has to be modified now

   if (str1.matches(queryStr) || str1.contains(orgQueryStr)){

to

   if (str1.matches(queryStr)){




Ex : 

 list of Strings: "test","detest","test0/1/1"

Filter 1:

     "te" ---> Prints "test","test0/1/1"

Filter 2:

     "te*" --- > Prints "test","test0/1/1"

Filter 3:

     "*te"

    Prints  all 

Upvotes: 0

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627082

The \w does not match /, it only matches alphanumeric and an underscore characters.

By looking at your code, I believe you want to match any character with a * in the filter. Any character but a newline can be matched with ..

Use

queryStr= queryStr.replaceAll("\\*+", ".*");
queryStr = ".*" + queryStr + (queryStr.endsWith(".*") ? "" : ".*"); 

See the IDEONE demo

If your * in the filter should only match any characters but whitespace, use \S instead of a .:

queryStr= queryStr.replaceAll("\\*", "\\\\S*");
queryStr = "\\S*" + queryStr + (queryStr.endsWith("\\S*") ? "" : "\\S*");

Upvotes: 1

Jas
Jas

Reputation: 1141

The forward slash "/" in your search string needs to be escaped (because it can be treated as a special character which is then consequently not being matched). So basically you would need to modify your expressions to something like :

static List<String> values = Arrays.asList("test","detest","test\\/1\\/1");

Edit: Added the escape for the backslashes as well

Upvotes: 0

Related Questions