* 仕様書

[REFS[
-[5] [CITE@en-us[UTS #18: Unicode Regular Expressions]]
( ([TIME[2012-07-19 21:56:19 +09:00]] 版))
<http://www.unicode.org/reports/tr18/#Categories>
-- [12] [CITE@en-us[UTS #18: Unicode Regular Expressions]], [TIME[2022-02-08T14:02:12.000Z]], [TIME[2022-11-12T14:47:25.731Z]] <https://unicode.org/reports/tr18/#Script_Property>
- [51] [CITE@en-us[UTS #18: Unicode Regular Expressions]], [TIME[2022-02-08T14:02:12.000Z]], [TIME[2022-11-13T09:19:29.145Z]] <https://unicode.org/reports/tr18/#Wildcard_Properties>
- [61] [CITE@en-us[UTS #18: Unicode Regular Expressions]], [TIME[2022-02-08T14:02:12.000Z]], [TIME[2022-11-13T09:31:45.108Z]] <https://unicode.org/reports/tr18/#Full_Properties>
- [63] [CITE@en-us[UTS #18: Unicode Regular Expressions]], [TIME[2022-02-08T14:02:12.000Z]], [TIME[2022-11-13T09:35:22.174Z]] <https://unicode.org/reports/tr18/#optional_properties>
- [67] [CITE@en-us[UTS #18: Unicode Regular Expressions]], [TIME[2022-02-08T14:02:12.000Z]], [TIME[2022-11-13T09:38:08.694Z]] <https://unicode.org/reports/tr18/#Compatibility_Properties>
-
[99] 
[CITE@en-us[UTS #18: Unicode Regular Expressions]], [TIME[2022-02-08T14:02:12.000Z]], [TIME[2022-11-14T09:00:21.917Z]] <https://unicode.org/reports/tr18/#Notation_for_Properties_of_Strings>
- [68] 
[CITE@en[[[perlunicode]] - Unicode support in Perl - Perldoc Browser]], [TIME[2022-11-13T09:55:49.000Z]] <https://perldoc.perl.org/perlunicode#Unicode-Character-Properties>
- [79] 
[CITE@en[[[perlunicode]] - Unicode support in Perl - Perldoc Browser]], [TIME[2022-11-13T12:01:52.000Z]] <https://perldoc.perl.org/perlunicode#Use-of-the-Is-Prefix>
- [84] 
[CITE@en[[[perlunicode]] - Unicode support in Perl - Perldoc Browser]], [TIME[2022-11-13T12:08:20.000Z]] <https://perldoc.perl.org/perlunicode#Blocks>
- [87] 
[CITE@en[[[perlunicode]] - Unicode support in Perl - Perldoc Browser]], [TIME[2022-11-13T12:15:22.000Z]] <https://perldoc.perl.org/perlunicode#Other-Properties>
- [89] 
[CITE@en[[[perlunicode]] - Unicode support in Perl - Perldoc Browser]], [TIME[2022-11-13T12:23:06.000Z]] <https://perldoc.perl.org/perlunicode#Wildcards-in-Property-Values>
-[3] [CITE@en-gb[[[perlunicode]] - perldoc.perl.org]]
( ([TIME[2012-11-23 23:18:45 +09:00]] 版))
<http://perldoc.perl.org/perlunicode.html#User-Defined-Character-Properties>
- [94] [CITE@en[[[perlunicode]] - Unicode support in Perl - Perldoc Browser]], [TIME[2022-11-13T12:38:51.000Z]] <https://perldoc.perl.org/perlunicode#Beyond-Unicode-code-points>


]REFS]

* Unicode正規表現における特性

[13] 
[[Unicode正規表現]]では、
[[UCD]] 等の[[特性][特性 (UCD)]]に基づく[[一致]]を表す機能が要求されています。
[SRC[>>12]]

[14] 
その具体的な構文は[[正規表現]]の実装に委ねられていますが、
例えば
[CODE[\p{[[Script]]=Greek}]]
や
[CODE[__&&[&&__:[[Script]]=Greek:__&&]&&__]]
のように表されます。
[SRC[>>12]]

[24] 
実例として次のような構文が示されています。
[SRC[>>12]]
各[[正規表現]]の実装は必ずしもこれに従う必要はありませんが、
大方これに近い形で実装しているようです。

- [25] [CODE[\p{]] [VAR[特性指定]] [CODE[}]] は、一致するものを表します。
[SRC[>>12]]
- [26] [CODE[\P{]] [VAR[特性指定]] [CODE[}]] は、一致''しない''ものを表します。
[SRC[>>12]]
- [27] [CODE[__&&[&&__:]] [VAR[特性指定]] [CODE[:__&&]&&__]] は、
一致するものを表します。 (旧構文)
[SRC[>>12]]
- [28] [CODE[__&&[&&__:^]] [VAR[特性指定]] [CODE[:__&&]&&__]] は、
一致''しない''ものを表します。 (旧構文)
[SRC[>>12]]
- [29] [VAR[特性指定]]は、[VAR[特性名]]か、
[VAR[特性名]]、[VAR[関係]]、[VAR[特性値]]です。
[SRC[>>12]]
-- [30] 
[VAR[特性名]]は、1個[[以上]]の[[ASCII英数字]],
[CODE[-]],
[CODE[_]],
[CODE(charname)@en[SP]]
の列です。
[SRC[>>12]]
-- [31] 
[VAR[関係]]は、
[CODE[=]],
[CODE[≠]],
[CODE[!=]]
のいずれかです。
[SRC[>>12]]
-- [32] 
[VAR[特性値]]は、
0個[[以上]]の[[リテラル]]
([[正規表現]]で特別な意味を持たない[[符号点]]または[[エスケープ]])
です。
[SRC[>>12]]
-- [52] 
[[ワイルドカード]]を使う場合の[VAR[特性値]]は、あるいは、
--- [53] 
[CODE[/]], [VAR[正規表現]], [CODE[/]] 
の列によって[[正規表現]]を指定できます。
[SRC[>>51]]
--- [54] 
[CODE[@]], [VAR[特性名]], [CODE[@]]
の列によって[[特性]]を指定できます。
[SRC[>>51]]
- [100] 
[CODE[\p]]
を[[域]]が[[符号点]]のものに限定したいときに、
[DFN[[CODE[\m]]]]
をかわりに[[符号点]]にも[[文字列]]にも適用可能なものとして使えます。 
[SRC[>>99]]




[69] 
[[Perl]] は [CODE[\p]], [CODE[\P]] に対応しています。
[SRC[>>68]]
([[Unicode]] は [[Perl]] 構文を採用したようです。 [SRC[>>12]])

[73] 
[[Perl]] では [CODE[\p{]] や [CODE[\P{]] の後に [CODE[^]]
を指定すると意味を反転させられます。  [SRC[>>68]]

[70] 
[[Perl]] は[VAR[特性指定]]が1文字だけのとき、 
[CODE[{]], [CODE[}]] を省略できるとしています。 [SRC[>>68]]

[EG[
[71] 
具体的には [CODE[General_Category]] の大分類だけを指定するときに、
[CODE[\pL]] のように書けます。
]EG]

** 特性データモデル

[15] 
[[Unicode正規表現]]における[[特性]]は、

- [16] その[RUBYB[域][domain]] ([[定義域]]) が[[Unicode符号点]]のもの、
[[文字列]]のものがあります。
[SRC[>>12]]
- [17] その[RUBYB[余域][codomain]] ([[値域]]) が
[RUBYB[二値][Binary]], 
[RUBYB[列挙][Enumerated]], 
[RUBYB[数値][Numeric]], 
[RUBYB[符号点][Code Point]],
[RUBYB[文字列][String]]、
それらの[RUBYB[集合][Set]]や[RUBYB[並び][List]]のものがあります。
[SRC[>>12]]

[98] 
[[絵文字]]系の[[特性]]や
[CODE[\p{Named_Sequence}]]
などいくつかの[[特性]]は、[[域]]が[[符号点]]でなく[[文字列]]です。
つまり [CODE[\p]] が1つの[[文字]]ではなく複数の[[文字列]]に[[一致]]する可能性があります。


[18] 
この値域の[[データ型]]は基本的には [[UCD]] の[[特性値]]のものに近いのですが、
少し違うので要注意です。

[19] 
二値型は、列挙型の特殊形で、 [CODE[True]] と [CODE[False]] の2つの値があります。
[SRC[>>12]]
[[UCD]] の[[二値特性]]の[[特性値]]では他にも多くの[[別名]]があります。

[20] 
列挙型は、 [[UCD]] の列挙型の他に、型録型にも対応 [SRC[>>12]] しています。
([[UCD]] では列挙型の値は固定的、型録型の値は将来追加される可能性がある、
という違いがあります。)

[21] 
符号点型は、文字列型の特殊形で、常に1つの[[符号点]]となります。
[SRC[>>12]]

[22] 
[[集合]]型は、一般に含むか含まないかの検査がなされます。
[SRC[>>12]]

[23] 
[[並び]]型は、含むか含まないかの検査をすることもありますが、
順序が意味を持つ場合があることに要注意とされています。
[SRC[>>12]]

[50] 
値の[[一致]]判定においては、一般に [[UAX #44]] の[[別名]]の一致の規則が適用されます。
(>>33, >>38)
[[特性]]によっては更に別の規定もあります。
[SEE[ [[General_Category]], [[文字の名前]] ]]

** 特性の名前と値

[33] 
[[UCD]] の[[特性]]の名前と値は、
[[UCD]] のデータファイルに[[別名]]として示されたもので、
省略名と長い名前を使うことが推奨されています。
両方の名前を認識すること、
[[UAX #44]] の一致の規則に従うことが強く推奨されています。
[SRC[>>12]]
(>>38)

;; [34] [[別名]]は、省略名と長い名前の他にその他の[[別名]]が存在することもあります。
それらにも対応するべきなのかどうかは言及されていません。
区別なくすべての[[別名]]に対応するのが無難と思われます。

[35] 
[VAR[特性指定]]において、
二値型の特性は名前だけを指定できます。
それ以外の特性は名前と値の両方が必要です。
[SRC[>>12]]

[47] 
あまり明確には示されていませんが、名前だけが指定されると [CODE[=[[True]]]]
の省略が想定されるようです。また、二値型だからといって省略しなければならないということでもなさそうです。


[36] 
例外的に、
[CODE[General_Category]]
と
[CODE[Script]] 
は、
名前と[VAR[関係]]を省略して値だけを指定できます。
[SRC[>>12]]


[80] 
[[Perl]] 5.26 から、
[CODE[Script]] のかわりに [CODE[Script_Extensions]]
が値だけで指定できるように[[非互換変更]]されました。
[SEE[ [[Script_Extensions]] ]]



[38] 
[[UCD特性]]の[[特性]]や[[特性値]]の[[別名]]の[[一致]]については、 [[UAX #44]] の規定によります。
[SRC[>>12 RL1.2]]

;; [49] 
二値型の時、値の[[別名]]も認められるべきなのかどうか明瞭ではありません。
[[Perl]] はすべて認めているようです [SRC[>>68]]。 

[48] 
ただし [CODE[is]] の無視については実装してなくても構いません。
[SRC[>>12 RL1.2]]

;; [43] 之は既存の実装が [CODE[is]] の有無を区別することが多いためです。
[SRC[>>12]]

[81] 
[[Perl]] は、 [[Perl]] 5.6 との[[後方互換性]]のため、
compound form でなくても書ける[[特性]]は先頭に [CODE[Is]] [CODE[Is_]]
があってもよいこととされています。 [SRC[>>79]]

[82] 
[[Perl]] でいう compound form とは名前と値を指定する形式のことです。 
ところが [CODE[\p{IsScript:Arabic}]] は [CODE[\p{Arabic}]]
と等しいとも例示されています。 [SRC[>>79]]
compound form でなく書かれているなら、ではなく compound form
でなくても書けるなら、と説明されているのは、
これが認められるということなのでしょうか。

[83] 
[[UCD]] の規定はこれを更に単純化したものになっています。
いっそその方が実装しやすそうです。

[85] 
[[Perl]] では、
[CODE[Block]] 
も名前と[VAR[関係]]を省略して値だけを指定できます。
更に、先頭に
[CODE[In]] や [CODE[Is]]
を付けることができます。
ただし、
他と衝突するものは除外されています。
[SRC[>>84]]

;; [86] 
これは [[Perl]] 独自のものです。
いくつかは現に衝突して使えません。
将来の [[Unicode]] 側の新規追加で更に使えないものが増える
([[プログラム]]を書く側から見れば[[非互換変更]]される)
可能性があり、
新しいコードでは避けるべきとされています [SRC[>>84]]。

[HISTORY[

[96] 
[[XML Schema]] の[[正規表現]]では [CODE[Is]] + [[ブロック名]]の二値型の特性が提案されていました。
[SRC[>>2]]


[2] [CITE@en[Unicode block names for use in XSD regular expressions]]
( ([TIME[2011-06-14 05:49:35 +09:00]] 版))
<http://www.w3.org/TR/2011/NOTE-xsd-unicode-blocknames-20110609/>

]HISTORY]

[42] 
[[UCD]] の[[別名]]以外に独自の[[別名]]を追加しても構いません。
[SRC[>>12]]

[40] 
[[正規表現]]の実装が対応している従来の[[特性]]の名前との[[後方互換性]]のため、
[[Unicode正規表現]]本来の[[特性]]の名前のかわりに、
[CODE[Alphabetic]]
を
[CODE[Unicode_Alphabetic]]
とするなど、
名前を変更することが認められています。
[SRC[>>12, >>61]]




;; [41] これら多くのバリエーションが認められている上、
対応している[[Unicodeの版]]によっても結果が変わってきます。
同じように見える[[正規表現]]でも、
ある実装が対応しているかどうかだけではなく、
どのように対応しているかもチェックしないといけません。


[37] 
[[Unicode正規表現]]の水準1では、数個の [[UCD特性]]への対応が要求されます。
[SRC[>>12 RL1.2]]

[62] 
[[Unicode正規表現]]の水準2では、加えて多数の [[UCD特性]]や関連規格の[[特性]]への対応が要求されます。
[SRC[>>61 RL2.7]]

[39] 
[[Unicode正規表現]]の水準1では、数個の互換性特性への対応が要求されます。
[SRC[>>12 RL1.2a, >>67]]
実装は Standard Recommendation と POSIX-compatible 
のどちらによるかを明記しなければなりません。
[SRC[>>12 RL1.2a]]


[44] 
[CODE[General_Category]] に属する特殊な名前として、
[CODE[Any]],
[CODE[Assigned]],
[CODE[ASCII]]
があります。
[SEE[ [[General_Category]] ]]

[64] 
その他いくつかの [[UCD特性]]や関連規格の[[特性]]へも対応して構わないとされます。
[SRC[>>63]]

[66] 
同じ構文で [[Unicode]] 以外の[[特性]]を実装することも特に禁止されていないようです。
ただし将来の [[Unicode]] の拡張と衝突するリスクは伴います。

[88]
[[Perl]] は [[Unicode]] にない独自のものを多数提供しています [SRC[>>87]]。

[1]
[[Perl]] 5.8.4には [CODE(perl)@en[\p{Compat}]] 
がありましたが、 5.8.7 ではなくなっているみたいです。
([[名無しさん]] [WEAK[2006-01-29 13:18:12 +00:00]])


[93] 
[[Perl]] では[[利用者]] ([[プログラム]]の開発者) が二値特性を定義できます。
[CODE[Is]] や [CODE[In]] で始まる名前を使いますが、
[[パッケージ名]]で修飾できるので
[CODE[[VAR[Foo]]::In[VAR[Bar]]]]
のような形になることもあります。
組み込みの名前と衝突する場合は、独自定義のものが優先されます。
[SRC[>>3]]



-*-*-

[55] 
[VAR[関係]]は明確に定められていませんが、
[CODE[=]] であれば指定された[[特性値]]と[[一致]]すること、
[CODE[≠]] や [CODE[!=]] であれば指定された[[特性値]]と[[一致]]しないことが求められるようです。

[72] 
[[Perl]] では [CODE[=]] のかわりに [CODE[:]] も使えます。 [SRC[>>68]]

-*-*-

[56] 
[VAR[特性値]]は水準1では値そのものの指定だけですが、
水準2では[[ワイルドカード]]に対応しなければなりません。
[SRC[>>51 RL2.6]]

[57] 
[[ワイルドカード]]としては、
[[特性値]]の条件を記述する[[正規表現]]を与えるか、
[[特性値]]と一致するべき[[特性]]の名前を与えることができます。
[SRC[>>51]]

[90] 
[[Perl]] では[[正規表現]]として記述できるものは、通常の
[[Perl]] の[[正規表現]]よりかなり制限されています。
[SRC[>>89]]


[58] 
[[特性値]]を[[正規表現]]によって判断する場合、
[[大文字と小文字]]の区別等の無視 (>>38) 
はなされません。
[SRC[>>51]]

[91] 
[[Perl]] では[[大文字と小文字]]の区別が行われません ([CODE[/i]] 相当)。
[[正規表現]]内で [CODE[(?-i)]] を明示的に指定すれば区別されるようになります。
ただし [CODE[\p{name}]] 
では区別されます。
[SRC[>>89]]

[92] 
[[Perl]] では一部の[[特性]]は[[正規表現]]一致を指定できません。
[SRC[>>89]]

[59] 
[[特性値]]を[[特性]]との一致によって判断する場合、
[[特性]]の名前として
[DFN[[CODE[identitiy]]]]
を指定できます。
この値は、その対象そのものを表します。
[SRC[>>51]]

[EG[
[60] 
[CODE[[[\p]]{toLowercase≠@identity@}]]
は、
[[小文字]]が元の[[符号点]]と等しくないことを意味します。
[SRC[>>51]]


]EG]

;; [65] [CODE[identity]] は [CODE[[[\p]]{[[identity]]=[VAR[x]]]] 
のように実装することも認められています [SRC[>>63]]。



[45] 
なお、実装は名前と値の組という概念を実装することも厳密には要求されていません。
同等の機能があれば足ります。
具体的には、
[CODE[\p{script=latin}]] の意味で [CODE[\p{script_latin}]]、
[CODE[\p{Block=Greek}]] の意味で [CODE[\p{Greek Block}]]
のようにも表現し得ることが例示されています。

;; [46] [[相互運用性]]の低下や[[プログラマー]]の混乱の元ですから、
あまり無闇矢鱈に一般的な構文から離れるのも如何かと思いますが。。。

* 大文字と小文字

[74] 
[CODE[\p]] による[[特性]]の一致判定のほとんどは、
[[大文字と小文字]]の区別をしないオプション ([CODE[/i]]) 
と無関係に動作します。
[SRC[>>68]]

[75] 
ところが [[Perl]] では次のものが [CODE[/i]] によって挙動が変化します。
[SRC[>>68]]

- [76] [CODE[Uppercase_Letter]], [CODE[Lowercase_Letter]], [CODE[Titlecase_Letter]]
→ [CODE[Cased_Letter]] 相当
- [77] [CODE[Uppercase]], [CODE[Lowercase]], [CODE[Titlecase]]
→ [CODE[Cased]] 相当
- [78] [CODE[PosixUpper]], [CODE[PosixLower]] → [CODE[PosixAlpha]] 相当

[97] 
[[UTS #18]] はこの問題について何も言及していません。

* 非Unicode文字

[95] 
[[Perl]] は[[Unicode符号点]]でないもの ([CODE[U-00110000]] [[以上]])
に対して [CODE[\p]] を検査する時、
(何の変哲もない) [[未割当符号点]]とみなします。
[SRC[>>94]]

* メモ




[4] >>3 Perl 5.8.8 では範囲を指定するときに [CODE(char)[[[U+0020]]]] 複数個でも良かったのですが、
Perl 5.10 以降では [CODE(char)[[[U+0009]]]] 1個でないといけないようです。


[6] [CITE[perldelta - search.cpan.org]]
( ([TIME[2014-05-30 01:08:05 +09:00]] 版))
<http://search.cpan.org/~rjbs/perl-5.20.0/pod/perldelta.pod#New_%5Cp%7BUnicode%7D_regular_expression_pattern_property>

[7] [CITE[perldelta - search.cpan.org]]
( ([TIME[2014-05-30 01:08:05 +09:00]] 版))
<http://search.cpan.org/~rjbs/perl-5.20.0/pod/perldelta.pod#%5Cp%7B%7D%2C_%5CP%7B%7D_matching_has_changed_for_non-Unicode_code_points.>

[8] [CITE[perlunicode - search.cpan.org]]
([TIME[2016-04-23 14:38:03 +09:00]] 版)
<http://search.cpan.org/dist/perl/pod/perlunicode.pod#Unicode_Character_Properties>

[9] [CITE@en-gb[perluniprops - perldoc.perl.org]]
([TIME[2015-06-15 22:59:25 +09:00]] 版)
<http://perldoc.perl.org/perluniprops.html>

[10] [CITE@en[Unicodeプロパティを使ったPerl正規表現 - Hatena Developer Blog]]
( ([TIME[2016-05-31 15:50:04 +09:00]]))
<http://developer.hatenastaff.com/entry/2016/05/31/123457>

[11] [CITE@en[Remove "Key Values and Unicode" section]]
([[garykac]]著, [TIME[2017-01-25 09:16:59 +09:00]])
<https://github.com/w3c/uievents/commit/8c621f6a46ba90996312ea12b96386eb51b92d42>

[101] [CITE@en[GitHub - tc39/proposal-regexp-unicode-sequence-properties: Proposal to add support for sequence properties in Unicode property escapes to ECMAScript regular expressions.]], [TIME[2023-04-28T10:01:53.000Z]] <https://github.com/tc39/proposal-regexp-unicode-sequence-properties>
