お知らせ: CrystalがRegexエンジンをアップグレードします
Crystalは、正規表現の処理に、その初期からPCREライブラリを使用しています。このライブラリには2つのメジャーバージョンがあり、Crystalはこれまで最初のバージョン(PCRE)を使用していました。しかし、このバージョンはサポート終了に達しました。そのため、次のリリース(1.8)では、その後継であるPCRE2に移行する予定です。
PCRE vs PCRE2
2つのライブラリバージョン、PCREとPCRE2は、ほとんど互換性があります。いくつかの小さな違いがあり、破壊的な変更を引き起こす可能性があります。しかし、大きな問題は発生しないと予想しています。最も注目すべきは、PCRE2はPCREよりも一部のエッジケースで厳密であることです。これは、PCREでは無効な正規表現が受け入れられていた場合でも、PCRE2では許可されないことを意味します。
残念ながら、移植を支援するガイドはありません。変更点の最も文書化されたリストは、Stackoverflowのこのスレッドです。
プラス面としては、PCRE2は興味深い機能のサポートを拡張しています。その機能の詳細については、Wikipediaの記事またはプロジェクトのドキュメントをご覧ください。
正規表現リテラルの検証
以下のロードマップを理解するためには、正規表現に関してコンパイラと標準ライブラリ間に既存の違いがあることを認識することが重要です。/(a|b)*/.match "abba"
のように記述した場合、*コンパイラ*は正規表現リテラル(/(a|b)/
)の有効性をチェックします。無効な式は構文エラーになります。次に、プログラムを実行すると、正規表現ライブラリへの*標準ライブラリ*バインディングが、一致の実際の実行を実行します。
この違いには結果があります。1つのライブラリで正規表現リテラルをチェックし、別のライブラリで実行することが可能です。
最後のリリース(1.7)では、コンパイラフラグを使用して、*標準ライブラリ*でPCRE2をオプトインする機能を既に追加しました。つまり、1.7とPCRE2がシステムにインストールされている場合、-Duse_pcre2
でプログラムまたはシャードをコンパイルし、実行時に正規表現が失敗するかどうかを確認できます。正規表現が失敗した場合、PCRE2に準拠するように書き直す必要があります。
今後のリリースでは、PCRE2がコンパイラと標準ライブラリでデフォルトで使用されます。何か問題が発生した場合に備えて、コンパイラフラグ-Duse_pcre
を使用して*標準ライブラリ*でPCREを使用することは引き続き可能です。ただし、コンパイラは常にPCRE2を使用して正規表現リテラルを検証します。これは、Crystalの構文に直接影響するため、一貫性のために重要です。
古いPCREを使い続ける必要がある場合、PCRE2の制限によりコンパイラがリテラルを無効と見なす場合は、リテラルを文字列リテラルとして式を受け取るRegex.new
呼び出しに変換できます。パフォーマンス上の理由から、Regex
インスタンスを(たとえば、定数に)キャッシュすることをお勧めします。
プロジェクトのPCRE2への移行
1.8のリリースまでまだ1か月以上あります。その間に、ナイトリービルドに変更を導入し、コミュニティがシャードとプロジェクトの非互換性をテストできるようにします。
そのため、準備のために、以下をお勧めします。
-
1.7を使用している場合は、コンパイラフラグ
-Duse_pcre2
を使用して、プロジェクトの状況を確認してください。 -
ナイトリービルドを使用している場合、既にPCRE2が使用されています。古い動作を取得するには、
-Duse_pcre
を追加する必要があります(これは*ランタイム*の動作にのみ影響し、構文や正規表現リテラルには影響しないことに注意してください)。 -
問題が発生している場合は、すべての正規表現を修正してください。
-
手順2で追加した場合は、
-Duse_pcre
を削除してください。1.9以降、PCREのサポートは保証されません。
この変更によりプロジェクトが失敗した場合は、お知らせください。情報を収集し、一般的な問題の修正を共有します。
1.8までにPCRE2に切り替えてください。