如何搜索特定格式的电子邮件列表?

How do I search email list for a particular format?

我正在寻找一个可以帮助我搜索电子邮件字符串列表的正则表达式,例如,如果我有一个 arraylist,其中列出了几封电子邮件,例如:firstname.lastname@company.comfirstname1.lastname1@company.com 我想搜索它们,以便在我的过滤器中添加 rst name1 ,它将显示 firstname1.lastname1@company.com ,我有过滤器代码并搜索每个匹配的字母。但是我想修改它并让它搜索点“。”之前或之后的字符。用正则表达式。我该怎么做? 这是我的过滤器搜索代码:

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();
            }
        }

其中

class ListItemsHolder {

public ArrayList<String>        Names;
}

包含格式为 firstname.lastname@company.com

的所有必要名称

假设您要传递最多两个参数。

我举个例子假设你提交了 'rst name1' 并且想找到 'firstname1.lastname1@company.com'。您想要的正则表达式是:

.*rst.*\..*name1.*\@

解释:

regex:   .*   rst   .*    \.  .*   ast   .*     \@
matches: fi   rst   name  .   l    ast   name   @

如果只有一个约束,'rst',那么您需要:

.*rst.*\@

伪代码(未测试):

arrayOfConstraintParts = constraint.split(" ");  // explode the constraint into an array of constraints
if (arrayOfConstraintParts.length >= 2) {        // If you have at least 2 constraints
    regex = ".*" . arrayOfConstraintParts[0] . ".*\..*" . arrayOfConstraintParts[1] . ".*\@";
} else {                                         // If you have only 1 constraint
    regex = ".*" . arrayOfConstraintParts[0] . ".*\@";
}

我觉得这很有用:https://regex101.com/

如果我没理解错的话,你可以把space换成.*\..*

例如,输入 jer ld 将变为 jer.*\..*ld 并将匹配 "jerry.seinfeld" -

请注意,它不会匹配 "jerald.melberg" - 因为 'jer' 和 'ld' 没有用“.”分隔- 这是你想要的吗?

正则表达式的解释 - 用文字 "zero or more characters (.*), followed by dot (\.) , followed by zero or more characters (.*)"

在您的代码中:

// just once before the loop:
String regex = constraint.replaceAll("[ .]+", ".*\..*")+".*@";
Pattern pattern = Pattern.compile(regex, CASE_INSENSITIVE);

// then in the loop,
// instead of:
// if (listItemsHolder.Names.get(i).toLowerCase().contains(constraint.toString().toLowerCase())) {
// do instead:
if (pattern.matcher(listItemsHolder.Names.get(i)).matches()) { ...

你没有明确定义这个过滤器应该有多敏感,所以假设我们想过滤每封给定字符串的电子邮件(如果有没有 space 的字符序列)或每封包含每个部分的电子邮件字符串(以 space 作为各部分之间的分隔符)。

没有正则表达式:

例如,您可以尝试使用以下内容:

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;
}

我用 List<String> 测试了此代码,因此与您的代码可能存在一些小差异,但它对我有用。这也只是一个例子,它可以很容易地以另一种方式实现。我只是不想过多地更改您的代码。

使用正则表达式:

添加创建正则表达式模式的小方法:

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;
}

您可以更改:

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

进入:

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

但是这个正则表达式不会包含 \. 部分,所以它不是强制性的,输入 j bau 它将匹配 jeff.bauser@company.comjerbauman@comp.com。但它可以很容易地改变,正如我上面写的,它没有明确定义它应该如何过滤名字,我也不确定这样的电子邮件可以包含多少部分,以及你想要允许什么样的输入。使用此方法,您还可以键入 f name l name,它会找到 firstname1.lastname1@company.com.