これは少し奇妙な質問であり、私が必要とするものは何でも実験していますが、私はまだ答えに興味があります.繰り返し部分の場合、文字列を単一の文字列オブジェクトとして保持し、必要に応じて呼び出され、それを処理する方がよいでしょうか。または、文字列を繰り返し部分を表す小さな文字列に分割し、必要に応じて連結する必要があります。 ?
例を挙げてみましょう: IP アドレスを検証するための正規表現を作成したい素朴なプログラマーがいるとしましょう (つまり、この正規表現が意図したとおりに機能しないことはわかっていますが、繰り返しの意味を示すのに役立ちます)。例の 2 番目の部分の入力を少し節約できます)。したがって、彼はこの関数を次のように記述します。
private bool isValidIP(string ip)
{
Regex checkIP = new Regex("\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?");
return checkIP.IsMatch(ip);
}
ここで、若いプログラマーは、"\d"、"\d?"、および "\" があることに気付きました。数回繰り返すだけです。これにより、ストレージ スペースを節約し、これが後で何を意味するかを思い出すことができるという考えが彼に与えられます。そこで彼は関数を作り直します:
private bool isValidIP(string ip)
{
string escape = "\\";
string digi = "d";
string digit = escape + digi;
string possibleDigit = digit + '?';
string IpByte = digit + possibleDigit + possibleDigit;
string period = escape + '.';
Regex checkIP = new Regex(IpByte + period + IpByte + period + IpByte + period + IpByte);
return checkIP.IsMatch(ip);
}
最初の方法は簡単です。プログラムの命令に38文字を格納するだけで、関数が呼び出されるたびにメモリに読み込まれます。2 番目のメソッドは、2 つの長さ 1 の文字列と 2 つの文字をプログラムの命令に格納する (私が推測する) だけでなく、これら 4 つを異なる順序に連結するためのすべての呼び出しも格納します。これにより、プログラムが呼び出されたときにメモリ内に少なくとも 8 つの文字列が作成されます (6 つの名前付き文字列、正規表現の最初の 4 つの部分の一時的な文字列、および前の文字列 + 正規表現の 3 つの文字列から作成された最終的な文字列)。この 2 番目の方法は、たまたま正規表現が探しているものを説明するのにも役立ちますが、最終的な正規表現がどのようになるかはわかりません。また、リファクタリングにも役立つ可能性があります。
繰り返しますが、どの方法が良いでしょうか?プログラムサイズとメモリ使用量のトレードオフと同じくらい簡単でしょうか? もちろん、このような単純なものでは、トレードオフはせいぜい無視できる程度ですが、もっと大きくて複雑な文字列の場合はどうでしょうか?
ああ、そうです。IP アドレスのより優れた正規表現は次のようになります。
^(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)(\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)){3}$
例としてうまく機能しないでしょうか?