我刚开始接触正则表达式,但经过大量阅读(并学到了很多东西),我仍然无法找到解决这个问题的好方法。
让我明确一点,我知道这个问题可能更好地使用非正则表达式来解决,但出于简洁起见,让我只说我需要使用正则表达式(相信我,我知道有更好的方法来解决这个问题)。
这是一个定义“有效”行的正则表达式:
"/^[AB][CD][EF][GH]$/m"
每行都有以下格式:第0个位置为A或B,第1个位置为C或D,第2个位置为E或F,第3个位置为G或H。我可以假设每行都恰好有4个字符。
我的目标是,给定其中一行,匹配所有其他包含两个或更多共同字符的行。
下面的示例假设以下内容:
-
$line
总是一个有效的格式。 -
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
*/
我知道一种方法可以达到预期的效果,就是使用以下正则表达式(该正则表达式仅适用于“ACFG”):"/^(?:AC.{2}|.CF.|.{2}FG|A.F.|A.{2}G|.C.G)$/m"
这个方法运行良好并且效率也还可以接受。但是,让我感到困扰的是,我必须基于$line生成它,而我更希望它不知道特定参数是什么。此外,如果稍后修改代码以匹配3个或更多字符,或者如果每行的大小从4增加到16,则此解决方案的可扩展性不太好。
感觉像是有什么非常简单的东西被忽视了。似乎这可能是重复的问题,但我查看过的其他问题似乎并没有真正解决这个特定的问题。
提前感谢你的回答!
更新:
看起来对于正则表达式答案,SO用户通常会发布一个正则表达式,并说“这应该适用于你”。
我认为这是一种半成品的答案。我真的想要理解正则表达式,因此,如果您可以在答案中包含详尽的(合理)说明来解释为什么该正则表达式:
A.有效
B.是最有效的(我认为有足够多的关于主题字符串的假设可以进行相当数量的优化)。
当然,如果您给出的答案可行,而其他人没有发布带有解决方案的答案,那么我将把它标记为答案 :)
更新2:
感谢大家的回答,提供了许多有用的信息,并且你们中的很多人都有有效的解决方案。我选择了我选择的答案,因为在运行性能测试后,它是最佳解决方案,平均具有与其他解决方案相等的运行时间。
我喜欢这个答案的原因:
1.所提供的正则表达式非常适用于更长的字符串
2.正则表达式看起来更简洁,易于像我这样的普通人进行解释。
但是,下面的所有答案也都非常详细地解释了为什么他们的解决方案是最佳的。如果您遇到这个问题,因为您正在尝试解决某些问题,请认真阅读所有答案,这对我非常有帮助。
F
和G
的位置必须在第三和第四个位置。 - Mike Ryan下面的示例假定以下情况
...BigFileOfLines.txt 只包含有效行
并且查看他的有效行正则表达式"/^[AB][CD][EF][GH]$/m"
,你会注意到 FG12 不是一个有效的行,因此不会被包括在他的有效行集合中。 - Jack