私は正規表現を知り始めたばかりですが、かなりの量の読書を行った (そしてかなり多くのことを学んだ) 後でも、この問題に対する適切な解決策を見つけることができませんでした。
はっきりさせておきますが、この特定の問題は正規表現を使用しない方が解決できることは理解していますが、簡潔にするために、正規表現を使用する必要があるとだけ言わせてください (信じてください。これを解決するためのより良い方法があることは知っています)。 )。
これが問題です。各行の長さがちょうど 4 文字の大きなファイルが与えられました。
これは、「有効な」行を定義する正規表現です。
"/^[AB][CD][EF][GH]$/m"
英語では、各行の位置 0 に A または B、位置 1 に C または D、位置 2 に E または F、位置 3 に G または H のいずれかが含まれます。各行は正確に 4 文字になると想定できます。長いです。
私がやろうとしているのは、これらの行の 1 つを指定して、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
*/
それが機能することを私が知っている1つの方法は、次のような正規表現を使用することです(次の正規表現は「ACFG」でのみ機能します:
"/^(?:AC.{2}|.CF.|.{2}FG|A.F.|A.{2}G|.C.G)$/m"
これは問題なく動作し、パフォーマンスは許容範囲です。しかし、それについて気に$line
なるのは、特定のパラメーターが何であるかを知らないようにしたい場合に、 に基づいてこれを生成する必要があることです。また、このソリューションは、後でコードがたとえば 3 文字以上に一致するように変更された場合、または各行のサイズが 4 から 16 に大きくなった場合、うまくスケーリングされません。
私が見落としている非常に単純なものがあるように感じます. また、これは重複した質問である可能性があるようですが、私が見た他の質問はどれも、この特定の問題に実際に対処しているようには見えません.
前もって感謝します!
アップデート:
正規表現の回答の標準は、SO ユーザーが単に正規表現を投稿して「これでうまくいくはずです」と言うだけのようです。
中途半端な回答だと思います。私は本当に正規表現を理解したいので、その正規表現の理由の完全な(理由の範囲内で)説明を回答に含めることができれば:
- A.作品
- B. 最も効率的です (かなりの量の最適化を行うことができる対象文字列について行うことができる十分な数の仮定があると思います)。
もちろん、あなたがうまくいく答えを出し、他の誰も答えを*解決策とともに*投稿しない場合、私はそれを答えとしてマークします:)
更新 2:
素晴らしい回答、多くの有益な情報、そして有効な解決策を提供してくださった皆様に感謝します。私が行った回答を選択したのは、パフォーマンス テストを実行した後、それが最良のソリューションであり、他のソリューションと同等のランタイムを平均化したからです。
私がこの答えを支持する理由:
- 指定された正規表現は、長い行に対して優れたスケーラビリティを提供します
- 正規表現は非常にきれいに見え、私のような凡人でも解釈しやすくなっています。
ただし、以下の回答も、そのソリューションが最適である理由を非常に徹底的に説明しているため、多くの功績があります。理解しようとしているためにこの質問に出くわした場合は、すべて読んでください。