【问题标题】:How to find sequenced pattern of characters in a string with PHP?如何使用 PHP 在字符串中查找字符的序列模式?
【发布时间】:2013-03-10 18:12:26
【问题描述】:

假设我有随机的文本块:

EAMoAAQAABwEBAAAAAAAAAAAAAAABAgMFBgcIBAkBAQABBQEBAAAAAAAAAAAAAAAGAgMEBQcBCBAAAQMDAgMEBQcIBQgGCwEAAQACAxEEBSEGMRIHQVFhE3GBIhQIkaGxwTJCI9FScoKSojMV8GLCUxbhstKDo7M0ZHOTJEQlF/HiQ2PDVHSExEUmGBEBAAIBAgMDCAgCCgMBAQEAAAECAxEEITEFQRIGUWFxgZGhIhPwscHRMlIUB0Jy4fGCkqLCI1MVFrLSQ2IzF//aAAwDAQACEQMRAD8A7+QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEEDwXkzpxHgusxi7NrnXF3G0NBLhzAkAeAqVH934r6bt57uTPSJ8ne1n2Rqycezy35VlRttwYu5DXNlLOcczOdpHM3hUUqtLs/wBxulZonXJ8vjp8caa+eOa5k6flrPLVcIbm3n/gytf4NcCVKtj1XbbqNcOSuT+W0W+pi3x2rzjRWWxUCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAggV5It2Uy8GNYAWmW6kr5MDftO8T3BRXxR4s2/SccTb48lvw0jnPnn8tfP6o1Ze02ds08OERzlid+/P5Orp5BHEeFuxxa0Dxpx9a+fOu+Iup9Tmfm30p+Ss92vr/N6bat/t67fDyjWfLLG79pt45YpAA8NdUAg9ngolTFNbedtqWi0avVicv5bLKFr2kSRltHaahrXCnylZcd6k208rDy4ItxlkUr5+XnZE1zxq0h3KfUQqv1GWsxeI0tHKY1rPtjRgVivKZU7HebrS491ybX+TWnO7V7PEn7w+f0rpPhb9zdxt7Rj3szkx/n/AI6+n88f4vTyebno8Wr3qTGvun7mawSxzsbNC4Pje0Oa9pqCD2grv+3z0zUi9Ji1bRrEx2wjtqzWdJ5wqq8pEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQU

规格:

patternABC >= 2 characters = groupABC IF groupABC occurs more than once
groupABC + (groupABC)n = sequence WHERE n >= 1 AND sequence > 6 characters

** 一个序列需要> 6个字符才能被评估

细分:

如何找到按顺序出现的任何重复模式?

QEBAQEBAQEBAQEBAQEBAQEBA

我还要数每组重复多少次:

QEBA QEBA QEBA QEBA QEBA QEBA = 6

此外,序列必须大于 6 个字符才能被评估:

NO GOOD: AA AA AA
GOOD: AA AA AA AA

如果可以将输出存储在关联数组中并删除重复条目,那将是理想的:

QEBA => 6, AA => 4, QEBA => 3, AA => 8, (QEBA => 6)<- REMOVE

有没有人有时间和意愿来解决这个问题? 如果你这样做,你就会摇滚!

【问题讨论】:

  • Regular Expression to detect repetition within a string 的可能重复项,第二个答案。
  • 这个正则表达式:/((\w+?)(\2))+/g 将匹配所有重复的字母序列。那我想你需要稍微操纵一下它们。
  • 感谢您的快速回复! @BillyMoon 那个正则表达式看起来肯定有帮助。谢谢。
  • “以 2 人或更多人为一组”?重复 2 次或更多次?或者至少要重复 2 个字符? AAAAAABAAAAAAB 呢?是否有AAs、AAAAAABs 或两者都重复? ABABABCBCBC 呢,应该 ABBC 还是两者都算?
  • patternABC >= 2 个字符 = groupABC groupABC + (groupABC)n = 序列 WHERE n >= 1 AND 序列 > 6 个字符 ** 一个序列需要 > 6 个字符才能被评估我希望这澄清了事情。

标签: php regex arrays string


【解决方案1】:
$str = 'EAMoAAQAABwEBAAAAAAAAAAAAAAABAgMFBgcIBAkBAQABBQEBAAAAAAAAAAAAAAAGAgMEBQcBCBAAAQMDAgMEBQcIBQgGCwEAAQACAxEEBSEGMRIHQVFhE3GBIhQIkaGxwTJCI9FScoKSojMV8GLCUxbhstKDo7M0ZHOTJEQlF/HiQ2PDVHSExEUmGBEBAAIBAgMDCAgCCgMBAQEAAAECAxEEITEFQRIGUWFxgZGhIhPwscHRMlIUB0Jy4fGCkqLCI1MVFrLSQ2IzF//aAAwDAQACEQMRAD8A7+QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEEDwXkzpxHgusxi7NrnXF3G0NBLhzAkAeAqVH934r6bt57uTPSJ8ne1n2Rqycezy35VlRttwYu5DXNlLOcczOdpHM3hUUqtLs/wBxulZonXJ8vjp8caa+eOa5k6flrPLVcIbm3n/gytf4NcCVKtj1XbbqNcOSuT+W0W+pi3x2rzjRWWxUCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAggV5It2Uy8GNYAWmW6kr5MDftO8T3BRXxR4s2/SccTb48lvw0jnPnn8tfP6o1Ze02ds08OERzlid+/P5Orp5BHEeFuxxa0Dxpx9a+fOu+Iup9Tmfm30p+Ss92vr/N6bat/t67fDyjWfLLG79pt45YpAA8NdUAg9ngolTFNbedtqWi0avVicv5bLKFr2kSRltHaahrXCnylZcd6k208rDy4ItxlkUr5+XnZE1zxq0h3KfUQqv1GWsxeI0tHKY1rPtjRgVivKZU7HebrS491ybX+TWnO7V7PEn7w+f0rpPhb9zdxt7Rj3szkx/n/AI6+n88f4vTyebno8Wr3qTGvun7mawSxzsbNC4Pje0Oa9pqCD2grv+3z0zUi9Ji1bRrEx2wjtqzWdJ5wqq8pEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQU';

preg_match_all( '/(\S{2,}?)\1+/', $str, $matches );

// Remove duplicates
$matches[0] = array_unique( $matches[0] ); 

foreach ( $matches[0] as $key => $value ) {
    if ( strlen( $value ) > 6 ) {
        $repeated = $matches[1][$key];
        $results[] = array( $repeated => count( explode( $repeated, $value ) ) - 1 );
    }    
}

print_r($results); 

/*
[AA] => 7
[QEBA] => 93
[CAgI] => 18
[EBAQ] => 18
*/

以上假设一个序列由非空格字符组成。

【讨论】:

  • 我需要知道每个序列以及其中包含多少组,因为它发生。因此,如果 QEBA 在一个地方出现 6 次,在另一个地方出现 18 次,这就是我想要存储它的方式。 QEBA => 6,QEBA => 18
  • @o0110o。输出存储在关联数组的数组中,每个数组包含一个序列作为键,重复计数作为其值。这意味着现在可以多次存储相同的序列。
  • 感谢您抽出宝贵时间提供帮助。我会告诉你进展如何。
  • 所以事实证明,我试图实现的目标与 GZIP 类似,所以这就是我最终使用的。我尝试了这些答案,我发现@MikeM 给出了一个更强大的答案,我可以轻松实现,尽管我真的很喜欢@ka 提供的正则表达式示例。再次感谢大家!
【解决方案2】:

使用preg_match_all('/(?:(.{6,})\1)/',$inputText,$sequences)获取序列
(注意:序列将保存在$sequences中)
解释正则表达式演示:http://regex101.com/r/rW4nE2

使用array_unique() 删除重复项。

遍历每个序列并且:
使用preg_match_all('/(.+?)(\1)(\1)?/',$sequence,$groups)获取群组
解释正则表达式演示:http://regex101.com/r/pC3pB7

如果需要,请使用count()

【讨论】:

  • 你可能还喜欢base64_decode()
  • 非常感谢!如果可行,我会尝试一下并将您的答案标记为正确。另外,有没有办法让 preg_match_all('/(.+?)(\1)(\1)?/',$sequence,$groups) 输出尽可能小的模式?我应该使用 groups[0] 再次运行它作为输入吗?
  • 太棒了,这个例子让我有点失望:regex101.com/r/pC3pB7。再次感谢您的帮助。感谢所有其他试图提供帮助的人!
  • 不客气。唯一重复的就是CAgI。另请参阅:regex101.com/r/jH8dV3
猜你喜欢
  • 1970-01-01
  • 2020-09-06
  • 2018-08-27
  • 1970-01-01
  • 1970-01-01
  • 2014-11-18
  • 2019-07-13
  • 2011-04-10
  • 1970-01-01
相关资源
最近更新 更多