首先,这比看起来要多更多的工作。
据我所知,这将是一种处理繁重的方法(并且可能不是您想在 SQL 中对游标做的事情(游标在效率方面有点糟糕)。
您必须为您的代码定义一种识别模式的方法。您还必须处理一组字符串匹配多个模式的优先级。例如,如果您实现以下模式标准(在您的示例中):
BK-M18B-48
BK-M18B-52
BK-M82B-44
BK-M82S-38
BK-M82S-44
BK-R50B-58
BK-R50B-62
.....
should generate BK-[A-Z]-[0-9][0-9][A-Z]-[0-9][0-9]
那么下一组结果可以有多个模式:
fedexcarepackage@outlook.com (example added for explanations)
fedexcarepackage@office.com
fedexcourierexpress@pisem.net
fedexcouriers@gmail.com ( another example added for explanations)
.....
可以生成:
fedexc%@%.% (as you said)
fedexc%@% (depending on processing)
fedexc[A-Z][A-Z]....%@%[A-Z]....[A-Z].[A-Z][A-Z][A-Z] (alphanumeris with '%' to compensate for length difference)
除此之外,如果您从字符串列表中删除 fedexcarepackage@outlook.com,您将获得 1 个您可能不想拥有的额外模式:
fedexc%@%i%.% (because they have 'i' somewhere between the '@' and '.' (dot)
无论如何,这是您在设计时必须考虑的事情。
我会给你一些你可以使用的基本逻辑:
- 创建一个函数来识别每个不同的模式(1 个模式/函数)。例如,1 个函数来检查字符串的静态片段(并附加通配符);另一个检测与您的条件匹配的 [A-Z],[0-9] 模式以使该模式有效;如果需要,可以针对不同的模式提供更多。
- 创建一个函数以使用您的模式测试字符串。所以说你有 4 个字符串,在比较前 2 个字符串时你会发现一个模式。然后您使用 this 函数来测试模式是否适用于第 3 和第 4 个字符串。
- 创建一个函数来测试两个模式是否互斥。例如,'PersonA@yahoo.%' 和 'PersonA@%.net' 模式不是相互排斥的,如果它们都被测试为真的话。 'Person%@yahoo.com' 和 'PersonB@yahoo.com' 是互斥的(两种模式都不能为真,所以 1 是多余的。
- 创建一个函数来组合不互斥的模式(可能包括在第 2 点和第 3 点中使用函数)。所以'PersonA@yahoo.%'和'PersonA@%.net'可以合并成'PersonA@%.%'
完成该设置后,循环遍历每个文本行,并根据每个模式标准将当前行与下一行进行比较。记录您发现的任何模式(在专用于该标准的变量中,(暂时不要混合它们)。
接下来是最困难的部分,最安全的方法是将找到的每个模式与每个字符串进行比较,以排除不适用于所有字符串的模式。但是,您可能会想出一种方法来组合模式(在同一类别中)而无需交叉检查
最后,在您将自己的模式列表缩小到每种模式类型 1 个模式之后。将它们合并为 1 或消除
请记住,在您的模式检测功能中,您可能需要多次测试每一行并组合模式。一些伪代码来演示:
Function CompareForStringMatches (String s1, String s2){ -- it should return a possible pattern found.
Array/List pattern;
int patternsFound=0;
For(i = 0, to length of shorter string){
For(x = 0, to length of shorter string){
if(longerString.contains(shorterString.substring(from i, to x)){
--record the pattern somewhere as:
pattern[patternsFound] = Replace(longerString, shorterString.Substring(from i, to x), '%') --pattern = longerString with substring replaced with '%' sign
patternsFound = patternsFound+1;
}
}
}
--After loops make another loop to check (partial) patterns against each other to eliminate patterns that are part of a larger pattern
--for instance Comparing 'random@asd.com' and 'sundom@asd.com' the patterns below should be found:
---compare'%andom@asd.com' and '%ndom@asd.com' and eliminate the first pattern, because both are valid, but second pattern includes the first one.
--You will have a lot of similar matches, but if you do this, you should end up with only a few patterns.
--after first cycle of checks do another one to combine patterns, where possible(for instance if you compare 'random@asd.com' and 'sundom@asd.net' you will end up with these 2 patterns'%ndom@asd.com' and 'Random@asd.%'.
--Since these patterns are true (because they were found during a comparison) you can combine them into '%ndom@asd.%'
--when you combine/eliminate all patterns, you should only have 1 left
return pattern[only pattern left];
}
PS:你可以更高效地做事,但如果你不知道从哪里开始,你可能需要做很长的路要走,并从第一个工作原型开始改进。
编辑/更新
我建议你做一个通配符检测方法,然后应用你在它之前实现的其他模式检查。
用于比较 2 个字符串(伪代码)的通配符检测,重处理版本:
比较 2 个字符串,检查 shorter 字符串的每个可能段是否在较长的范围内:
for(int i = 0; i<shorterString.Length;i++){
for(int x = 0; i<shorterString.Length;i++){
if(longerString.contains(shorterString.substring(i,x))){ --from i to x
possiblePattern.Add(longerString.replace(shorterString.substring(i,x),'*')
--add to pattern list
}
}
--Next compare partal matches and eliminate ones that are a part of larger pattern
--So '*a@gmail.com' and '*na@yahoo.com' comparison should eliminate '*na@gmail.com', because if shorter pattern (with more symbols removed) is valid, then similar one with an extra symbol is part of it
--When that is done, combine remaining matches if there's more than 1 left.
--Remember, all patterns are valid if your first loop was correct, so '*@gmail.com' and 'personA@*.com' can be combined into '*@*.com
}
至于字母数字检测。我建议您首先检查所有字符串的长度。如果它们相同,则运行通配符模式检测方法(针对所有这些)。完成后,仅在通配符中查找模式匹配项。
所以,您会从通配符检测运行中得到类似BK-*-* 的模式。在第二次迭代循环中,取 2 个字符串并仅提取由通配符表示的子字符串(使用数组或等价物来存储子字符串,确保不要将单个字符串的两个通配符组合成 1 个字符串)。
因此,如果您与上面找到的模式 (BK-*-*) 进行比较:
BK-M18B-48
BK-M18B-52
消除静态字符后,您应该得到以下字符串集进行处理:
Set 1:M18B and 48
Set 2:M18B and 52
将每个字符与相同位置的相反字符串进行比较,并检查字符是否与您的类别匹配(例如 if String1[0].isaLetter AND String2[0].isaLetter)。如果他们确实将该 1 个字符添加到模式中,如果不是:
- 添加通配符(将导致类似 BK-[A-Z]*[0-9][0-9]-[0-9][0-9] 的模式。如果这样做,将相邻的通配符组合到1.
- Pattern 为 false,您应该中止不返回任何模式的检查。
使用此基本逻辑循环字符串,为每组 2 个字符串创建(并存储!!!!)模式。循环模式,使用通配符检测(可能是更轻的版本)来组合/消除模式。因此,如果你从不同的字符串集中获得像 '@yahoo.com' 和 '@gmail.com' 这样的模式,你应该将它们组合成 '@.com'
请记住,这里有很多优化空间。