Search code examples
androidregexandroid-layoutandroid-fragmentsandroid-search

How do I search email list for a particular format?


I am looking for a regular expression that can help me search a list of email strings such that say, if I have an arraylist with a couple of emails listed such that : firstname.lastname@company.com , firstname1.lastname1@company.com I would like to search through them such that in my filter if I add rst name1 ,it will display firstname1.lastname1@company.com , I have the filter code in place and it searches thru every matched letter. however I would like to modify it and make it search the characters before or after the dot "." with regular expressions. How do I go about it? Here's my filter search code :

protected synchronized FilterResults performFiltering(CharSequence constraint) {

                FilterResults results = new FilterResults();

                if (constraint != null && constraint.length() > 0) {

                    ArrayList<Integer> filterList = new ArrayList<>();

                    int iCnt = listItemsHolder.Names.size();
                    for (int i = 0; i < iCnt; i++) {
                        if(listItemsHolder.Types.get(i).toString().indexOf("HEADER_")>-1){
                            continue;
                        }
                        if (listItemsHolder.Names.get(i).toLowerCase().contains(constraint.toString().toLowerCase())) {
                            if(filterList.contains(i))
                                continue;

                            filterList.add(i);

                        }

                    }

                    results.count = filterList.size();

                    results.values = filterList;
                }else {

                    results.count = listItemsHolder.Names.size();

                    ArrayList<Integer> tList = new ArrayList<>();
                    for(int i=0;i<results.count;i++){
                        tList.add(i);
                    }

                    results.values = tList;

                }

                return results;
            }


            //Invoked in the UI thread to publish the filtering results in the user interface.
            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                ArrayList<Integer> resultsList = (ArrayList<Integer>)results.values;
                if(resultsList != null) {
                    m_filterList = resultsList;
                }
                notifyDataSetChanged();
            }
        }

where

class ListItemsHolder {

public ArrayList<String>        Names;
}

contains all the necessary names in the format firstname.lastname@company.com


Solution

  • You didn't explicitly define how sensitive this filter should be, so let's say we want to filter every email with given string (if there is char sequence without space) or every email containing every part of string (with space as delimiter between parts).

    WITHOUT REGEX:

    you could for example try with something like:

    boolean itFit; //additional variable
    List<String> results;
    
    if (constraint != null && constraint.length() > 0) {
    
        ArrayList<Integer> filterList = new ArrayList<>();
    
        int iCnt = listItemsHolder.Names.size();
        for (int i = 0; i < iCnt; i++) {
            itFit = true;     // default state of itFit is ture,
            if(listItemsHolder.Types.get(i).toString().indexOf("HEADER_")>-1){
                continue;
            }
            for(String con : constraint.toString().split("\\s")) {   // constraint as string is splitted with space (\s) as delimiter, the result is an array with at least one element (if there is no space)
                if (!listItemsHolder.Names.get(i).toLowerCase().contains(con.toLowerCase())) {
                    itFit = false;    // if email doesn't contains any part of splitted constraint, the itFit value is changed to false 
                }
    
            }
            if(itFit && !filterList.contains(i)){   // if itFit is true, add element to list
                filterList.add(listItemsHolder.Names.get(i));
            }
        }
    
        results = filterList;
    }
    

    I tested this code with List<String> so there coulde be some little differences with your code, but it works fo me. Also it is just example, it could be easily implemented in another way. I just did't want to change your code too much.

    WITH REGEX:

    With addition of small method to create regex pattern:

    public String getRegEx(CharSequence elements){
        String result = "(?i).*";
        for(String element : elements.toString().split("\\s")){
            result += element + ".*";
        }
        result += "@.*";  // it will return String like "(?i).*j.*bau.*"
        return result;
    }
    

    you can change:

    if (listItemsHolder.Names.get(i).toLowerCase().contains(constraint.toString().toLowerCase())) {
    

    into:

    if (listItemsHolder.Names.get(i).matches(getRegEx(constraint))) {
    

    However this regex will not contain a \. part, so it will not be obligatory, and with input j bau it will match jeff.bauser@company.com, and jerbauman@comp.com. But it could be changed easily, and as I wrote above, it is not explicitly defined how it should filter names, also I am not sure how many parts could such email contain, and what kind of input you want to allow. With this method, you can also type f name l name and it will find firstname1.lastname1@company.com.