Я только знакомлюсь с регулярными выражениями, но после того, как я довольно много прочитал (и многому научился ), я все еще не смог понять хороший решение этой проблемы.
Поясню, я понимаю, что эту конкретную проблему лучше решить не с помощью регулярных выражений, но для краткости позвольте мне просто сказать, что мне нужно использовать регулярные выражения (trust меня, я знаю, что есть лучшие способы решить эту проблему ).
Вот в чем проблема. Мне дан большой файл, каждая строка которого имеет длину ровно 4 символа.
Это регулярное выражение, определяющее «допустимые» строки.:
"/^[AB][CD][EF][GH]$/m"
В английском языке каждая строка имеет либо A, либо B на позиции 0, либо C, либо D на позиции 1, либо E, либо F на позиции 2, и либо G, либо H в позиции 3. Я могу предположить, что каждая строка будет иметь длину ровно 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.
Просто кажется, что есть что-то удивительно простое, что Я пропускаю.Также кажется, что это может быть повторяющийся вопрос, но ни один из других вопросов, которые я рассматривал, действительно не решает эту конкретную проблему.
Заранее спасибо!
Обновление:
Кажется, что нормой для ответов Regex является то, что пользователи SO просто публикуют регулярное выражение и говорят: «Это должно сработать для вас».
Думаю, это половинчатый ответ. Я действительно хочу понять регулярное выражение, поэтому, если вы можете включить в свой ответ подробное (в пределах разумного )объяснение того, почему это регулярное выражение:
Конечно, если вы дадите ответ, который работает, и никто другой не опубликует ответ *с *решением, я отмечу его как ответ:)
Обновление 2:
Спасибо всем за отличные ответы, много полезной информации, и у многих из вас были правильные решения. Я выбрал ответ, потому что после проведения тестов производительности это было лучшее решение, в среднем равное времени выполнения с другими решениями.
Причины, по которым я предпочитаю этот ответ.:
Тем не менее, большое спасибо приведенным ниже ответам за то, что они очень подробно объяснили, почему их решение является лучшим. Если вы столкнулись с этим вопросом, потому что пытаетесь понять, пожалуйста, прочитайте их все, они мне очень помогли.