このサイトの詳細 |
はじめに |
正規表現クイックスタート |
正規表現チュートリアル |
置換文字列チュートリアル |
アプリケーションと言語 |
正規表現の例 |
正規表現リファレンス |
置換文字列リファレンス |
書籍レビュー |
印刷可能なPDF |
このサイトについて |
RSSフィードとブログ |
Unicode は、現存および過去のすべての言語のすべての文字とグリフを定義することを目的とした文字セットです。ますます多くのソフトウェアが複数の言語、あるいはあらゆる言語をサポートする必要があるため、近年、Unicode は急速に普及しています。異なる言語に異なる文字セットを使用することは、プログラマーやユーザーにとって非常に面倒です。
残念ながら、Unicode は正規表現に関しては独自の要件と落とし穴をもたらします。このチュートリアルで説明した正規表現フレーバーのうち、Java、XML、および.NETは Unicode ベースの正規表現エンジンを使用しています。Perl はバージョン 5.6 から Unicode をサポートしています。PCRE はオプションで Unicode サポートを有効にしてコンパイルできます。PCRE は、その名前「Perl 互換」にもかかわらず、\pトークンに対して許容される内容において、柔軟性がはるかに低いことに注意してください。PCRE に基づく PHP preg 関数は、正規表現に /u オプションが追加されると Unicode をサポートします。Ruby はバージョン 1.9 から正規表現で Unicode エスケープとプロパティをサポートしています。XRegExp は、JavaScript に Unicode プロパティのサポートをもたらします。
RegexBuddy の正規表現エンジンは、バージョン 2.0.0 から完全に Unicode ベースになっています。RegexBuddy 1.x.x は Unicode をまったくサポートしていませんでした。PowerGREP は、バージョン 3.0.0 から同じ Unicode 正規表現エンジンを使用しています。以前のバージョンでは、8 ビット(つまり非 Unicode)の正規表現エンジンで grep する前に、Unicode ファイルを ANSI に変換していました。EditPad Pro は、バージョン 6.0.0 から Unicode をサポートしています。
ほとんどの人はàを単一の文字と考えるでしょう。残念ながら、「文字」という言葉の意味によっては、必ずしもそうである必要はありません。
このチュートリアルで説明されているすべての Unicode 正規表現エンジンは、単一の Unicodeコードポイントを単一の文字として扱います。このチュートリアルでドットが単一の文字に一致すると説明されている場合、これは Unicode 用語では「ドットは単一の Unicode コードポイントに一致する」と解釈されます。Unicode では、àは、2つのコードポイントとしてエンコードできます。U+0061 (a) の後に U+0300 (グレイブアクセント) が続きます。この状況では、.をàに適用すると、aアクセントなしで一致します。^.$は、文字列が2つのコードポイントで構成されているため、一致に失敗します。^..$はà.
に一致します。Unicode コードポイント U+0300 (グレイブアクセント) は、結合文字です。結合文字ではないコードポイントの後に、任意の数の結合文字を続けることができます。上記の U+0061 U+0300 のようなこのシーケンスは、画面上に単一の書記素として表示されます。
残念ながら、àは、単一の Unicode コードポイント U+00E0 (グレイブアクセント付きの a) でエンコードすることもできます。この二重性の理由は、多くの歴史的な文字セットが「グレイブアクセント付きの a」を単一の文字としてエンコードしているためです。Unicode の設計者は、マークと基本文字を分離するという Unicode の方法(これにより、レガシー文字セットでサポートされていない任意の組み合わせが可能になります)に加えて、一般的なレガシー文字セットとの一対一のマッピングがあると便利だと考えました。
単一の書記素を、単一のコードポイントとしてエンコードされているか、結合文字を使用して複数のコードポイントとしてエンコードされているかに関係なく、Perl、PCRE、PHP、Boost、Ruby 2.0、Java 9、および Just Great Software アプリケーションで一致させるのは簡単です。単に\Xを使用します。あなたは\Xをドットの Unicode バージョンと考えることができます。ただし、1つ違いがあります\Xは常に改行文字と一致しますが、ドットはドットが改行に一致する一致モードを有効にしない限り、改行文字と一致しません。
.NET、Java 8以前、および Ruby 1.9 では、\P{M}\p{M}*+または(?>\P{M}\p{M}*)を妥当な代替として使用できます。任意の数の書記素に一致させるには、(?>\P{M}\p{M}*)+を\X+.
特定のコードポイントとの一致特定の Unicode コードポイントに一致させるには、\uFFFFを使用します。ここで、FFFF は、一致させたいコードポイントの 16 進数です。常に 4 桁の 16 進数を指定する必要があります。例:はà\u00E0
は、単一のコードポイント U+00E0 としてエンコードされている場合にのみ一致します。Perl、PCRE、Boost、およびstd::regex は、特定の Unicode コードポイントに一致させるには、構文をサポートしていません。これらは代わりに\x{FFFF}を使用します。中かっこで囲まれた 16 進数では、先頭のゼロを省略できます。\x自体は有効な正規表現トークンではないため、\x{1234}が\x1234回一致すると誤解されることは決してありません。常に Unicode コードポイント U+1234 に一致します。\x{1234}{5678}は、コードポイント U+1234 に正確に 5678 回一致しようとします。
Java では、正規表現トークン特定の Unicode コードポイントに一致させるには、は、標準同等性を有効にした場合でも、指定されたコードポイントにのみ一致します。ただし、同じ構文特定の Unicode コードポイントに一致させるには、は、Java ソースコードで Unicode 文字をリテラル文字列に挿入するためにも使用されます。Pattern.compile("\u00E0")は、àの単一コードポイントと二重コードポイントの両方のエンコードに一致しますが、Pattern.compile("\\u00E0")は、単一コードポイントバージョンのみに一致します。Java の文字列リテラルとして正規表現を記述する場合、バックスラッシュをエスケープする必要があることを忘れないでください。前者の Java コードは正規表現àをコンパイルし、後者はを使用します。ここで、FFFF は、一致させたいコードポイントの 16 進数です。常に 4 桁の 16 進数を指定する必要があります。例:をコンパイルします。実行する内容によっては、この違いが重要になる場合があります。
JavaScript は、RegExp クラスを通じて Unicode サポートを提供していませんが、文字列構文の一部として、単一の Unicode コードポイントを一致させるための特定の Unicode コードポイントに一致させるには、をサポートしています。
XML Schema および XPath には、Unicode コードポイントを一致させるための正規表現トークンはありません。ただし、のような XML エンティティを使用して、正規表現にリテラルコードポイントを簡単に挿入できます。
Unicode は、複雑さだけでなく、新しい可能性ももたらします。その1つは、各 Unicode 文字が特定のカテゴリに属しているということです。「文字」カテゴリに属する単一の文字を一致させることができます\p{L}を使用します。そのカテゴリに属していない単一の文字を一致させるには、\P{L}.
を使用します。ここでも、「文字」は実際には「Unicode コードポイント」を意味します。\p{L}は、「文字」カテゴリの単一のコードポイントに一致します。入力文字列がàU+0061 U+0300 としてエンコードされている場合、aアクセントなしで一致します。入力がàU+00E0 としてエンコードされている場合、àアクセント付きで一致します。その理由は、コードポイント U+0061 (a) と U+00E0 (à) の両方が「文字」カテゴリにあり、U+0300 が「マーク」カテゴリにあるためです。
これで、\P{M}\p{M}*+が\X. \P{M}と同等である理由が理解できたはずです。一致しないコードポイントをマークし、\p{M}*+は、結合マークであるゼロ個以上のコードポイントに一致します。任意のダイアクリティカルマークを含む文字に一致させるには、\p{L}\p{M}*+を使用します。この最後の正規表現は常にàに、どのようにエンコードされているかに関係なく、一致します。所有量指定子は、バックトラッキングが、後に続く結合マークなしに非マークを一致させないようにします。\P{M}\p{M}*+は、決してそうしないでしょう。\XPCRE、PHP、および .NET は、
トークンの中かっこで囲まれた部分を確認するときに、大文字と小文字を区別します。\pトークン。\p{Zs}はあらゆる種類の空白文字に一致しますが、\p{zs}はエラーをスローします。このチュートリアルで説明されている他のすべての正規表現エンジンは、中かっこで囲まれたカテゴリの大文字と小文字を無視して、両方の場合で空白に一致します。それでも、以下のプロパティのリストで私がやったのと同じ大文字と小文字の組み合わせを使用する習慣を付けることをお勧めします。これにより、正規表現はすべての Unicode 正規表現エンジンで動作するようになります。
標準表記に加えて、\p{L}Java、Perl、PCRE、JGsoft エンジン、および XRegExp 3 では、省略表記\pLを使用できます。省略表記は、一文字の Unicode プロパティでのみ機能します。\pLlは\p{Ll}と同等ではありません。それは\p{L}lと同等で、Alまたはàlまたは、リテラルl.
が続く任意の Unicode 文字に一致します。Perl、XRegExp、および JGsoft エンジンは、長表記\p{Letter}もサポートしています。以下に、すべての Unicode プロパティの完全なリストを示します。アンダースコアを省略したり、代わりにハイフンやスペースを使用したりできます。
Unicode 標準では、割り当てられた各コードポイント(文字)を 1 つのスクリプトに配置します。スクリプトとは、特定の人間が書くシステムで使用されるコードポイントのグループです。タイ語のようなスクリプトはタイ語単一の人間言語に対応します。ラテン文字のような他のスクリプトはラテン文字複数の言語にまたがります。
一部の言語は複数のスクリプトで構成されています。日本語の Unicode スクリプトはありません。代わりに、Unicode はひらがな, カタカナ, 漢字、そしてラテン文字日本語の文書が通常構成されるスクリプトを提供します。
特別なスクリプトは共通スクリプトです。このスクリプトには、広範囲のスクリプトに共通するあらゆる種類の文字が含まれています。あらゆる種類の句読点、空白、およびその他の記号が含まれています。
割り当てられたすべての Unicode コードポイント(でマッチングされるもの)\P{Cn})は、正確に 1 つの Unicode スクリプトの一部です。割り当てられていないすべての Unicode コードポイント(でマッチングされるもの)\p{Cn})は、どの Unicode スクリプトにも属していません。
JGsoft エンジン、Perl、PCRE、PHP、Ruby 1.9、Delphi、およびXRegExpは、Unicode スクリプトを照合できます。以下にリストを示します。
Perl および JGsoft フレーバーでは、以下を使用できます\p{IsLatin}の代わりに\p{Latin}。「Is」構文は、次のセクションで説明するように、スクリプトとブロックを区別するのに役立ちます。PCRE、PHP、および XRegExp は「Is」プレフィックスをサポートしていません。
Java 7 は Unicode スクリプトのサポートを追加しました。他のフレーバーとは異なり、Java 7 では「Is」プレフィックスが必要です。
Unicode 標準では、Unicode 文字マップを異なるブロックまたはコードポイントの範囲に分割しています。各ブロックは、「チベット語」のような特定のスクリプトの文字や、「点字パターン」のような特定のグループに属する文字を定義するために使用されます。ほとんどのブロックには、Unicode 標準の将来の拡張のために予約された、割り当てられていないコードポイントが含まれています。
Unicode ブロックはスクリプトと 100% 対応しないことに注意してください。ブロックとスクリプトの重要な違いは、ブロックが以下に示すようにコードポイントの単一の連続した範囲であるということです。スクリプトは、Unicode 文字マップ全体から取得された文字で構成されます。ブロックには、割り当てられていないコードポイントが含まれる場合があります(つまり、でマッチングされるコードポイント)。\p{Cn})。スクリプトには、割り当てられていないコードポイントは決して含まれません。一般に、Unicode スクリプトを使用するか Unicode ブロックを使用するか不明な場合は、スクリプトを使用してください。
たとえば、通貨ブロックにはドル記号と円記号は含まれていません。それらは、両方が通貨記号であり、円記号がラテン文字ではない場合でも、代わりに Basic_Latin ブロックと Latin-1_Supplement ブロックにあります。これは、ASCII 標準にドル記号が含まれ、ISO-8859 標準に円記号が含まれているという歴史的な理由からです。名前だけに基づいて、以下に示すブロックを盲目的に使用すべきではありません。代わりに、実際に一致する文字の範囲を見てください。RegexBuddyのようなツールは、これに非常に役立ちます。Unicode プロパティ\p{Sc}または\p{Currency_Symbol}は、Unicode ブロックよりも適切な選択肢になります\p{InCurrency_Symbols}すべての通貨記号を見つけようとするとき。
すべての Unicode 正規表現エンジンが、Unicode ブロックをマッチさせるために同じ構文を使用するわけではありません。Java、Ruby 2.0、およびXRegExpは、上記のように\p{InBlock}という構文を使用します。.NET および XML は代わりに\p{IsBlock}を使用します。Perl と JGsoft フレーバーは、両方の表記をサポートしています。正規表現エンジンがサポートしている場合は、「In」表記を使用することをお勧めします。「In」は Unicode ブロックにのみ使用できますが、「Is」は使用している正規表現のフレーバーに応じて、Unicode プロパティやスクリプトにも使用できます。「In」を使用することで、同様の名前のプロパティやスクリプトではなく、ブロックをマッチさせていることが明確になります。
.NET および XML では、ブロック名でアンダースコアを省略する必要がありますが、ハイフンは保持する必要があります。例: 次のように使用します。\p{IsLatinExtended-A}の代わりに\p{InLatin_Extended-A}。Java では、ハイフンを省略する必要があります。.NET および XML も名前を大文字と小文字を区別して比較しますが、Perl、Ruby、および JGsoft フレーバーは大文字と小文字を区別せずに比較します。Java 4 は大文字と小文字を区別します。Java 5 以降は、「Is」プレフィックスについては大文字と小文字を区別しますが、ブロック名自体は大文字と小文字を区別しません。
ブロックの実際の名前は、すべての正規表現エンジンで同じです。ブロック名は Unicode 標準で定義されています。PCRE および PHP は、Unicode スクリプトをサポートしているにもかかわらず、Unicode ブロックをサポートしていません。
アクセント付き文字がエンコードされるさまざまな方法によって作成される落とし穴を常に念頭に置いておく必要がありますが、常にそれらを心配する必要があるわけではありません。入力文字列と正規表現が同じスタイルを使用していることがわかっている場合は、まったく心配する必要はありません。このプロセスは Unicode 正規化と呼ばれます。Java、C#、VB.NET など、ネイティブの Unicode サポートを備えたすべてのプログラミング言語には、文字列を正規化するためのライブラリルーチンがあります。マッチを試みる前に、対象と正規表現の両方を正規化すると、矛盾は発生しません。
Java を使用している場合は、Pattern.compile() の 2 番目のパラメータとして CANON_EQ フラグを渡すことができます。これにより、Java 正規表現エンジンは正準等価文字を同一として扱うようになります。正規表現àU+00E0 としてエンコードされたものは、àU+0061 U+0300 としてエンコードされたものと一致し、その逆も同様です。現在、他の正規表現エンジンはマッチング中に正準等価性をサポートしていません。
キーボードで à キーを入力すると、私が知っているすべてのワードプロセッサはコードポイント U+00E0 をファイルに挿入します。したがって、自分で入力したテキストを操作している場合は、自分で入力した正規表現は同じように一致します。
最後に、従来の Windows (多くの場合「ANSI」と呼ばれる) または ISO-8859 コードページを使用してエンコードされたテキストファイルを検索するためにPowerGREPを使用している場合、PowerGREP は常に一対一の置換を使用します。すべての Windows または ISO-8859 コードページはアクセント付き文字を単一のコードポイントとしてエンコードするため、ほとんどすべてのソフトウェアはファイルを Unicode に変換するときに各文字に単一の Unicode コードポイントを使用します。
| クイック スタート | チュートリアル | ツール & 言語 | 例 | リファレンス | 書籍レビュー |
| はじめに | 目次 | 特殊文字 | 非印刷文字 | 正規表現エンジンの内部構造 | 文字クラス | 文字クラスの減算 | 文字クラスの共通部分 | 短縮形文字クラス | ドット | アンカー | 単語境界 | 選択 | オプション項目 | 繰り返し | グループ化とキャプチャ | 後方参照 | 後方参照、パート 2 | 名前付きグループ | 相対後方参照 | ブランチリセットグループ | 自由な間隔とコメント | Unicode | モード修飾子 | アトミックグループ化 | 所有量指定子 | 先読みと後読み | 先読み、パート 2 | マッチからテキストを除外する | 条件 | バランシンググループ | 再帰 | サブルーチン | 無限再帰 | 再帰と量指定子 | 再帰とキャプチャ | 再帰と後方参照 | 再帰とバックトラッキング | POSIX ブラケット式 | ゼロ長マッチ | マッチの継続 |
ページ URL: https://regular-expressions.dokyumento.jp/unicode.html
最終更新日: 2021 年 8 月 12 日
サイト最終更新日: 2024 年 3 月 15 日
Copyright © 2003-2024 Jan Goyvaerts. All rights reserved.