他の回答ですでに詳細に説明されていることは知っていますが(一般的に使用される正規表現のより良い説明を含む)、最近、説明なしでこの正規表現に出くわしたので、自分でコメントを追加しました。他の人が見られるように、ここで共有することも考えました。
最初に注意すべきことは、正規表現が整数に単項を使用することです。したがってString s = new String(new char[n]);
、Java コードでは、整数n
をその数の ( '\0'
) 文字の文字列に変換します。この文字列に含まれる文字は重要ではありません。単項にとって重要なのは長さです。(Java 11+ の代替手段は、たとえば であった可能性がString s = "x".repeat(n);
あり、それでも意図したとおりに機能します。)
正規表現自体については:
"(?x) .? | ( \\2?+ (\\1|^.) )* .." # Since this is a Java-String, where the `\` are escaped
# as `\\` and `String#matches` also implicitly adds a
# leading/trailing `^...$` to regex-match the entire
^(?x) .? | ( \2?+ (\1 |^.) )* ..$ # String, the actual regex will be this:
# The `(?x)` is used to enable comments and whitespaces,
# so let's ignore those for now:
^.?|(\2?+(\1|^.))*..$
( )* # First capture group repeated 0 or more times.
# On each iteration it matches one Fibonacci number.
|^. # In the first iteration, we simply match 1 as base case.
# Afterwards, the ^ can no longer match, so the
# alternative is used.
\2?+ # If possible, match group 2. This ends up being the
# Fibonacci number before the last. The reason we need
# to make his optional is that this group isn't defined
# yet in the second iteration. The reason we have the `+`
# is to prevent backtracking: if group 2 exists, we
# *have* to include it in the match, otherwise we would
# allow smaller increments.
(\1| ) # Finally, match the previous Fibonacci number and store
# it in group 2 so that it becomes the second-to-last
# Fibonacci number in the next iteration.
# This in total ends up adding Fibonacci numbers starting
# at 1 (i.e. 1,2,3,5,8,... will add up to 3,6,11,19,...
.. # They are all two less than the Fibonacci numbers, so
# we add 2 at the end.
# Now it's only missing the 0 and 1 of the Fibonacci
.?| # numbers, so we'll account for those separately