如何搜索特定格式的电子邮件列表?
How do I search email list for a particular format?
我正在寻找一个可以帮助我搜索电子邮件字符串列表的正则表达式,例如,如果我有一个 arraylist
,其中列出了几封电子邮件,例如:firstname.lastname@company.com
, firstname1.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.com
和 jerbauman@comp.com
。但它可以很容易地改变,正如我上面写的,它没有明确定义它应该如何过滤名字,我也不确定这样的电子邮件可以包含多少部分,以及你想要允许什么样的输入。使用此方法,您还可以键入 f name l name
,它会找到 firstname1.lastname1@company.com
.
我正在寻找一个可以帮助我搜索电子邮件字符串列表的正则表达式,例如,如果我有一个 arraylist
,其中列出了几封电子邮件,例如:firstname.lastname@company.com
, firstname1.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.com
和 jerbauman@comp.com
。但它可以很容易地改变,正如我上面写的,它没有明确定义它应该如何过滤名字,我也不确定这样的电子邮件可以包含多少部分,以及你想要允许什么样的输入。使用此方法,您还可以键入 f name l name
,它会找到 firstname1.lastname1@company.com
.