PHP Regex Проверяет, имеют ли две строки два общих символа

Я только знакомлюсь с регулярными выражениями, но после того, как я довольно много прочитал (и многому научился ), я все еще не смог понять хороший решение этой проблемы.

Поясню, я понимаю, что эту конкретную проблему лучше решить не с помощью регулярных выражений, но для краткости позвольте мне просто сказать, что мне нужно использовать регулярные выражения (trust меня, я знаю, что есть лучшие способы решить эту проблему ).

Вот в чем проблема. Мне дан большой файл, каждая строка которого имеет длину ровно 4 символа.

Это регулярное выражение, определяющее «допустимые» строки.:

"/^[AB][CD][EF][GH]$/m" 

В английском языке каждая строка имеет либо A, либо B на позиции 0, либо C, либо D на позиции 1, либо E, либо F на позиции 2, и либо G, либо H в позиции 3. Я могу предположить, что каждая строка будет иметь длину ровно 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
*/

Один из способов, которым я знаю, что будет работать, состоит в том, чтобы иметь регулярное выражение, подобное следующему (следующее регулярное выражение будет работать только для "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. Регулярное выражение выглядит намного чище, и его легче интерпретировать простым смертным, таким как я.

Тем не менее, большое спасибо приведенным ниже ответам за то, что они очень подробно объяснили, почему их решение является лучшим. Если вы столкнулись с этим вопросом, потому что пытаетесь понять, пожалуйста, прочитайте их все, они мне очень помогли.

12
задан Paul Hazen 23 April 2012 в 03:07
поделиться