PHP Regex检查两个字符串是否共享两个公共字符

Pau*_*zen 12 php regex preg-match-all

我刚刚开始了解正则表达式,但经过相当多的阅读(并且学习了很多)后,我仍然无法找到解决这个问题的好方法.

让我说清楚,我明白这个特殊问题可能更好地解决使用正则表达式,但为了简洁起见,我只想说我需要使用正则表达式(相信我,我知道有更好的方法来解决这个问题) ).

这是问题所在.我给了一个大文件,每行的长度恰好是4个字符.

这是一个定义"有效"行的正则表达式:

"/^[AB][CD][EF][GH]$/m" 
Run Code Online (Sandbox Code Playgroud)

在英语中,每一行在位置0处具有A或B,在位置1处具有C或D,在位置2处具有E或F,并且在位置3处具有G或H.我可以假设每行将精确地为4个字符长.

我正在尝试做的是给出其中一行,匹配包含2个或更多共同字符的所有其他行.

以下示例假定以下内容:

  1. $line 始终是有效的格式
  2. BigFileOfLines.txt 仅包含有效行

例:

// Matches all other lines in string that share 2 or more characters in common
// with "$line"
function findMatchingLines($line, $subject) {
    $regex = "magic regex I'm looking for here";
    $matchingLines = array();
    preg_match_all($regex, $subject, $matchingLines);
    return $matchingLines;
}

// Example Usage
$fileContents = file_get_contents("BigFileOfLines.txt");
$matchingLines = findMatchingLines("ACFG", $fileContents);

/*
 * Desired return value (Note: this is an example set, there 
 * could be more or less than this)
 * 
 * BCEG
 * ADFG
 * BCFG
 * BDFG
*/
Run Code Online (Sandbox Code Playgroud)

我知道一种方法工作有如下内容(以下正则表达式将仅适用于"ACFG"工作正则表达式:

"/^(?:AC.{2}|.CF.|.{2}FG|A.F.|A.{2}G|.C.G)$/m"

这项工作正常,性能可以接受.让我感到困扰的是,我必须根据它来生成这个$line,我宁愿让它不知道具体的参数是什么.此外,如果稍后修改代码以匹配说3个或更多字符,或者如果每行的大小从4增加到16,则此解决方案不能很好地扩展.

感觉就像我忽略了一些非常简单的东西.似乎这可能是一个重复的问题,但我所看到的其他问题似乎都没有解决这个特殊问题.

提前致谢!

更新:

似乎Regex答案的标准是SO用户只需发布一个正则表达式并说"这应该对你有用".

我认为这是一个半途而废的答案.我真的想要理解正则表达式,所以如果你能在答案中包含一个彻底的(在合理范围内)解释为什么那个正则表达式:

  • A.工作
  • B.效率最高(我觉得可以对主题字符串做出足够数量的假设,可以进行大量的优化).

当然,如果你给出一个有效的答案,没有其他人用*解决方案发布答案​​,我会将其标记为答案:)

更新2:

谢谢大家的好评,很多有用的信息,以及很多有效的解决方案.我选择了我的答案,因为在运行性能测试之后,它是最好的解决方案,与其他解决方案平均运行时间相同.

我赞成这个答案的原因是:

  1. 给定的正则表达式为更长的行提供了出色的可伸缩性
  2. 正则表达式看起来更清晰,对于像我这样的凡人来说更容易理解.

然而,很多信誉都归功于以下答案以及解释为什么他们的解决方案是最好的.如果你遇到这个问题,因为这是你想要弄清楚的东西,请给他们一个阅读,帮助我极大.

Jac*_*ack 4

你为什么不直接使用这个正则表达式$regex = "/.*[$line].*[$line].*/m";呢?

对于你的例子,这意味着$regex = "/.*[ACFG].*[ACFG].*/m";