【问题标题】:get the pattern of unknown strings using sql?使用 sql 获取未知字符串的模式?
【发布时间】:2016-03-17 13:11:24
【问题描述】:

我的数据库有数千个未知字符串,它们可能是电子邮件,电话号码

但它们不适合我,意味着它们对我来说不是电子邮件或手机号码,它们只是我的字符串,但我想要它们的通用模式,所以这里是用于示例目的的字符串

链接到示例click here

现在我想要的是输出这个文件,如果模式匹配 3 次,我正在做的是

 DECLARE @strs2 nvarchar(255)
 DECLARE @patternTable table(
id int ,



  order by p.pat 

但是我的例子返回了这个

       485-2889
       485-2889
       ) 485-2889
       ) 485-2889
       .aol.com/aol/search?
      .aol.com/aol/search?
        gmail.com 
     gmail.com 

但我想为模式添加这个

   [a-zA-Z 0-9] [a-zA-Z 0-9] [a-zA-Z 0-9] -  485-2889

对于 gmail [a-zA-Z 0-9] [a-zA-Z 0-9]@gmail.com

【问题讨论】:

  • 我不会在数据库中做这样的事情。这不是关系工作。将数据拉入代码层,在那里处理,然后在需要时写回。

标签: sql regex database sql-server-2008


【解决方案1】:

首先,这比看起来要更多的工作。 据我所知,这将是一种处理繁重的方法(并且可能不是您想在 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 个模式/函数)。例如,1 个函数来检查字符串的静态片段(并附加通配符);另一个检测与您的条件匹配的 [A-Z],[0-9] 模式以使该模式有效;如果需要,可以针对不同的模式提供更多。
  2. 创建一个函数以使用您的模式测试字符串。所以说你有 4 个字符串,在比较前 2 个字符串时你会发现一个模式。然后您使用 this 函数来测试模式是否适用于第 3 和第 4 个字符串。
  3. 创建一个函数来测试两个模式是否互斥。例如,'PersonA@yahoo.%' 和 'PersonA@%.net' 模式不是相互排斥的,如果它们都被测试为真的话。 'Person%@yahoo.com' 和 'PersonB@yahoo.com' 是互斥的(两种模式都不能为真,所以 1 是多余的。
  4. 创建一个函数来组合不互斥的模式(可能包括在第 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 St​​ring2[0].isaLetter)。如果他们确实将该 1 个字符添加到模式中,如果不是:

  • 添加通配符(将导致类似 BK-[A-Z]*[0-9][0-9]-[0-9][0-9] 的模式。如果这样做,将相邻的通配符组合到1.
  • Pattern 为 false,您应该中止不返回任何模式的检查。

使用此基本逻辑循环字符串,为每组 2 个字符串创建(并存储!!!!)模式。循环模式,使用通配符检测(可能是更轻的版本)来组合/消除模式。因此,如果你从不同的字符串集中获得像 '@yahoo.com' 和 '@gmail.com' 这样的模式,你应该将它们组合成 '@.com'

请记住,这里有很多优化空间。

【讨论】:

  • 我可以通过替换您的代码来添加我的代码,以便我们开始讨论
  • @CMM5 解决方案:作为 Zero sais,您似乎正在寻找表格条目的共同模式。但是从哪里开始,在哪里停止呢?模式^.*$ 匹配所有条目。模式找到了,工作完成了吗?还是您需要更精确?但那么精确到什么程度呢? a@gmail.coma@yahoo.com 都匹配 ^a@[a-o]{5}\.com$。但这可能不是您想要的模式。那么你如何定义你正在寻找的模式呢?我的意思是:你根本不应该寻找代码,而应该寻找规则。这些可能很难定义。
  • 我知道你是对的但我需要 [a-zA-Z0-9][0-9]a@gmail.com 等,因为 'a@gmail.com' 和之前一样添加它
  • @CMM5 解决方案我已经更新了答案以大致描述模式检测的逻辑。如果您发现某些特定部分令人困惑,请告诉我 - 我会澄清。除此之外,我认为没有什么可说的。通配符检测将是大多数模式搜索的核心(因为它会发现部分匹配和不匹配),因此请确保尽可能高效。
猜你喜欢
  • 2023-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-07
  • 1970-01-01
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多