【发布时间】:2012-05-03 14:17:48
【问题描述】:
我刚刚开始了解正则表达式,但是在阅读了很多内容(并且学到了很多东西)之后,我仍然无法找到解决这个问题的好方法。
让我说清楚,我知道这个特定问题可能会更好地解决而不是使用正则表达式,但为了简洁起见,我只想说我需要使用正则表达式(相信我,我知道有更好的方法来解决这个问题)。
这就是问题所在。我得到了一个大文件,每行正好是 4 个字符。
这是一个定义“有效”行的正则表达式:
"/^[AB][CD][EF][GH]$/m"
在英语中,每行在位置 0 处有 A 或 B,在位置 1 处有 C 或 D,在位置 2 处有 E 或 F,在位置 3 处有 G 或 H。我可以假设每一行都是正好 4 个字符长。
我想要做的是给这些行之一,匹配包含 2 个或更多常见字符的所有其他行。
以下示例假设如下:
-
$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.作品
- 乙。是最有效的(我觉得可以对主题字符串做出足够多的假设,可以进行相当多的优化)。
当然,如果你给出了一个有效的答案,并且没有其他人*with* 一个解决方案发布答案,我会将其标记为答案:)
更新 2:
感谢大家的精彩回复、很多有用的信息,并且你们中的很多人都有有效的解决方案。我选择了我所做的答案,因为在运行性能测试后,它是最好的解决方案,平均运行时间与其他解决方案相同。
我赞成这个答案的原因:
- 给定的正则表达式为较长的行提供了出色的可伸缩性
- 正则表达式看起来更清晰,对于像我这样的凡人来说更容易解释。
但是,以下答案也非常值得称赞,因为他们非常彻底地解释了为什么他们的解决方案是最好的。如果您遇到这个问题是因为这是您想要弄清楚的问题,请给他们全部阅读,这对我有很大帮助。
【问题讨论】:
-
我绝对同意您在更新中提出的观点。之前问过正则表达式问题,我很少发现“这个有效”的答案是最好的或最有帮助的。当然,这也适用于其他问题。
-
当你说两个常见的字符时,它们必须在同一个位置吗?例如,您是否将“FBGA”视为与“ACFG”有两个常见字符? (确实如此,但他们处于不同的位置)。
-
@mathematical.coffee 是的,他们需要在同一个位置。
-
只是对您接受的答案的后续评论。它可以带来很多积极因素,我认为您的其他受访者不会认为您想要。在 ACFG 的情况下,这将匹配 FG12,这不是我认为我们其他人所假设的,因为我们认为
F和G的位置必须位于第 3 和第 4 位。跨度> -
@MikeRyan 是的,但是如果您仔细阅读问题的粗体部分
The below example assumes the following...BigFileOfLines.txt contains only valid lines并查看他的有效行正则表达式"/^[AB][CD][EF][GH]$/m",您会注意到FG12 不是有效的行,因此不会包含在他的有效行集中。
标签: php regex preg-match-all