ShiftJISRegexp - Shift-JISで書かれた正規表現

 

名称

ShiftJIS::Regexp - Shift-JISで書かれた正規表現


概要

  use ShiftJIS::Regexp qw(:all);
  match('あお12', '/p{Hiragana}{2}/p{Digit}{2}');
# これは次行と等価です。
  match('あお12', '/pH{2}/pD{2}');
  match('あいいううう', '^あい+う{3}$');
  replace($str, 'A', 'A', 'g');


詳細

このモジュールは、正規表現をShift-JISで書いてPerlで用いるための幾つかの関数を提供します。

このモジュールにおいて正しい Shift-JIS 文字は、以下の正規表現にマッチするものでなければなりません。

    [/x00-/x7F/xA1-/xDF]|[/x81-/x9F/xE0-/xFC][/x40-/x7E/x80-/xFC]

したがって、MacOS Japaneseの一バイト文字領域での拡張分 ([/x80/xA0/xFD-/xFF]) は取り扱うことができません。

マルチバイトエンコーディングにおける誤マッチを避けるため、このモジュールでは、マッチングが毎回文字境界上で行われるためのパターンを正規表現に付加しています。 perlfaq6 の ``How can I match strings with multibyte characters?'' を参照。

また、後述の「誤マッチを避ける」も参照してください。

関数

re(PATTERN)
re(PATTERN, MODIFIER)
Shift-JISで書かれた正規表現をPerlでパース可能なように変換して返します。

PATTERNには、Shift-JISで書かれた正規表現を文字列として与えます。

MODIFIERとしては、以下の修飾子(複数指定可)を文字列で与えます。

     i  大文字/小文字を区別しない (ASCIIアルファベット)
     I  大文字/小文字を区別しない (ギリシャ文字、キリル文字、全角ラテン文字)
     j  平仮名と片仮名を区別しない(しかし半角片仮名は考慮されません)
     s  文字列を単一行として扱う
     m  文字列を複数行として扱う
     x  バックスラッシュの後または文字クラスの中にない空白文字 (つまり [/x20/n/r/t/f])
        を無視する。しかしコメントは認識しません。
     o  一回パースして(コンパイルではありません!) 結果を内部にキャッシュします。

re('^コンピューター?$')は、'コンピューター'または'コンピュータ'にマッチします。

re('^らくだ$','j') は、'らくだ', 'ラクダ', 'らクだ', などにマッチします。

o修飾子

     while (<DATA>) {
        print replace($_, '(perl)', '<strong>$1</strong>', 'igo');
     }
     は、次のコードよりも効率がよいでしょう
     while (<DATA>) {
        print replace($_, '(perl)', '<strong>$1</strong>', 'ig');
     }
     なぜなら後者では関数が呼ばれるたびに毎回パターンをパースするからです。

match(STRING, PATTERN)
match(STRING, PATTERN, MODIFIER)
組み込みの m// 演算子のように動作します。ただし、 @list = $string =~ m/PATTERN/g と異なり、キャッシュの括弧を忘れずに付けてください。括弧は自動的には付きません。
    $string = "あいうえお";
    @list = match($string, '[いえ]', 'g'); # だめ。結果にゴミが混じる!
    @list = match($string,'([いえ])','g'); # 良し。

PATTERNにはパターンを文字列として与えます。

MODIFIERには修飾子を文字列として与えます。

     i,I,j,s,m,x,o   re()の説明をご覧ください。
     g  グローバルマッチ
     z  パターンが空文字列にマッチするものであることを関数に知らせる。
        (すみません。これを使うべきかどうかを自動的には判別できません。)

z修飾子

パターンが空文字列にマッチするものである場合、z修飾子がないと以下のように1回だけマッチすべきところを2回マッチすることがあります。 z修飾子は、これを防ぎます。

     replace('アイウイイエ', '(?=イ)', 'あ', 'g');  # アああイウああイああイエ
     replace('アイウイイエ', '(?=イ)', 'あ', 'gz'); # アあイウあイあイエ

replace(STRING or SCALAR REF, PATTERN, REPLACEMENT)
replace(STRING or SCALAR REF, PATTERN, REPLACEMENT, MODIFIER)
組み込みの s/// 演算子のように動作します。

第一変数としてスカラーへのリファレンスを渡すと、スカラーを変更して置換回数を返します。

第一変数として文字列(リファレンスではない)を渡すと、与えられたスカラーは変更せず、置換後の文字列を返します。

    my $str = '金1530000円';
    1 while replace(/$str, '(/pD)(/pD{3})(?!/pD)', '$1,$2');
    print $str; # 金1,530,000円

MODIFIERには修飾子を文字列として与えます。

     i,I,j,s,m,x,o   re()の説明をご覧ください。
     g,z             match()の説明をご覧ください。

jsplit(PATTERN or ARRAY REF of [PATTERN, MODIFIER], STRING)
jsplit(PATTERN or ARRAY REF of [PATTERN, MODIFIER], STRING, LIMIT)
組み込みの split() 演算子のように動作します。

スカラーコンテキスト/ボイドコンテキストで特殊配列 @_ に結果を入れることはしません。スカラーコンテキストでは、見つかったフィールドの数を返すだけです。

PATTERNには、Shift-JISで書かれた正規表現を文字列として与えます。

    jsplit('/', 'あいう/えおメ^');

PATTERN' ' を与えても特別な意味はありません。単に、組み込みの CORE::split / / と同様に、一個のスペースにより分割するだけです。

空白類文字(この場合、和字間隔(全角スペース)も空白類文字とみなします)で分割したい場合には、PATTERNに未定義値を与えるか、 splitspace() 関数を使ってください。

    jsplit(undef, '   This  is   perl.');
    splitspace('   This  is   perl.');
    # ('This', 'is', 'perl.')

パターンに修飾子をつけたい場合は、無名配列 [PATTERN, MODIFIER] を第一引数に用いることができます。

    jsplit([ 'あ', 'jo' ], '01234あいうえおアイウエオ');

あるいは、埋め込み修飾子(後述)を用いることもできます。

    jsplit('(?jo)あ', '01234あいうえおアイウエオ');

MODIFIERには修飾子を文字列として与えます。

     i,I,j,s,m,x,o   re()の説明をご覧ください。

splitspace(STRING)
splitspace(STRING, LIMIT)
組み込みの split(' ', STRING, LIMIT) のように動作します。空白類文字(和字間隔(全角スペース)を含む)により文字列 STRING を分割し、結果のリストを返します。文字列先頭の空白類文字はフィールドを作りません。

注意: splitspace(STRING, LIMIT)jsplit(undef, STRING, LIMIT) と等価です。

splitchar(STRING)
splitchar(STRING, LIMIT)
組み込みの split(//, STRING, LIMIT) のように動作します。文字列 STRING を文字ごとに分割したリストを返します。

注意: splitchar(STRING, LIMIT)jsplit('', STRING, LIMIT) と等価です。

基本的な正規表現

   正規表現          意味
   ^               文字列の先頭にマッチします。
                   ただし 'm' 修飾子を使った場合は、行の先頭にマッチします。
   $               文字列末尾か、末尾の改行文字 /n の前にマッチします。
                   ただし 'm' 修飾子を使った場合は、行の末尾にマッチします。
   .               改行文字 /n 以外の任意の一文字にマッチします。
                   ただし 's' 修飾子を使った場合は、/nを含む任意の一文字にマッチします。
   /A              文字列の先頭にマッチします。
   /Z              文字列末尾か、末尾の改行文字 /n の前にマッチします。
   /z              文字列末尾だけにマッチします。('(?!/n)/Z' と同じ)
   /C              一個のオクテットにマッチします。
   /j              任意の一文字にマッチします。
                   つまりこのモジュールで言う [/0-/x{FCFC}] と同じです。
   /J              改行文字 /n 以外の任意の一文字にマッチします。
                   つまりこのモジュールで言う [^/n] と同じです。
     * /j と /J とは、このモジュールによる拡張です。例えば、
        match($_, '(/j{5})/z') は末尾の五文字(/n を含む)を返します。
        match($_, '(/J{5})/Z') は末尾の五文字(/n は除く)を返します。

メタ文字

   /a              ベル       (BEL)
   /b              後退       (BS) * 文字クラスの中だけ *
   /e              エスケープ (ESC)
   /f              書式送り   (FF)
   /n              改行       (LF)
   /r              復帰       (CR)
   /t              水平タブ   (HT)
   /0              ナル文字   (NUL)
   /ooo            一バイト文字を八進数で指定
   /xhh            一バイト文字を十六進数で指定
   /x{hhhh}        二バイト文字を十六進数で指定
   /c[             制御文字
      例えば /012 /123 /x5c /x5C /x{824F} /x{9Fae} /cA /cZ /c^ /c? など。

文字クラス

文字クラスの中には、リテラル文字、メタ文字、定義済み文字クラスを入れることができます。また、文字クラス中では、文字の範囲を使うことができます。文字の範囲の端点は、リテラル文字かメタ文字で指定します。

Shift-JIS 文字の順序は: 0x00 .. 0x7F, 0xA1 .. 0xDF, 0x8140 .. 0x9FFC, 0xE040 .. 0xFCFC.

このモジュールが文字の範囲を展開するときは、Shift-JIS領域外となるバイト並びを適切に飛ばしますので、Shift-JISにおける第一バイト・第二バイトの範囲を意識する必要がありません。例えば、Shift-JISでは、第二バイトが0x7Fとなることは許されませんので、 [/x{8340}-/x{8396}]は、[/x{8340}-/x{837E}/x{8380}-/x{8396}]と同じ意味になります。また、[/0-/x{fcfc}] は、Shift-JIS の任意の一文字にマッチします。文字クラス中では、Shift-JIS文字として不正なバイトまたはバイト列(例えば re('[/xA0-/xFF]'))はエラーになり、使用できません。

等価文字クラス

バージョン 0.13 から POSIX の等価文字クラス [=x=] がサポートされます。例えば、[[=あ=]][ぁァァあアア] と、 [[=P=]][pPpP] と、[[=4=]][44] と、それぞれ等価です。これらは、文字クラスの中で [[=c=]][[=p=][=e=][=r=][=l=]] のようにして使うことができます。

[=x=] の中には、任意の文字リテラルまたはメタ文字 /xhh, /x{hhhh} を用いることができます。等価文字クラスに属する文字のうち、どの文字を使ってもかまいません。例えば、[=あ=], [=ア=], [=/x{82A0}=], [=/xB1=] などは、互いに同じ意味を持ちます。

[[=か=]]'か', 'カ', 'カ', 'が', 'ガ', 'ガ', 'ヵ' にマッチします。('ガ' は二文字ですが、照合要素としては一つです。濁音、半濁音をもつカナの照合要素は、濁音、半濁音を表す二文字の半角片仮名からなる文字列を含みます。

[[===]] は、等号か全角等号とマッチします。[[=[=]] は、始め角括弧または全角始め角括弧とマッチします。[[=]=]] は、終り角括弧または全角終り角括弧とマッチします。[[=/=]] は、円記号または全角円記号とマッチします。

定義済み文字クラス

   通常の形式     省略形     POSIX形式         文字および文字の範囲による定義
   /d                                          [0-9]
   /D                                          [^0-9]
   /w                                          [0-9A-Z_a-z]
   /W                                          [^0-9A-Z_a-z]
   /s                                          [/t/n/r/f ]
   /S                                          [^/t/n/r/f ]
   /p{Xdigit}     /pX        [[:xdigit:]]      [0-9A-Fa-f]
   /p{Digit}      /pD        [[:digit:]]       [0-90-9]
   /p{Upper}      /pU        [[:upper:]]       [A-ZA-Z]
   /p{Lower}      /pL        [[:lower:]]       [a-za-z]
   /p{Alpha}      /pA        [[:alpha:]]       [A-Za-zA-Za-z]
   /p{Alnum}      /pQ        [[:alnum:]]       [0-9A-Za-z0-9A-Za-z]
   /p{Word}       /pW        [[:word:]]        [_/p{Digit}/p{European}/p{Kana}/p{Kanji}]
   /p{Punct}      /pP        [[:punct:]]       [!-/:-@[-`{-~。-・、-!´-_―-〓∈-∩∧-∃∠-∬Å-¶◯─-╂]
   /p{Graph}      /pG        [[:graph:]]       [/p{Word}/p{Punct}]
   /p{Print}      /pT        [[:print:]]       [/x20/x{8140}/p{Graph}]
   /p{Space}      /pS        [[:space:]]       [/x20/x{8140}/x09-/x0D]
   /p{Blank}      /pB        [[:blank:]]       [/x20/x{8140}/t]
   /p{Cntrl}      /pC        [[:cntrl:]]       [/x00-/x1F/x7F]
   /p{ASCII}                 [[:ascii:]]       [/x00-/x7F]
   /p{Roman}      /pR        [[:roman:]]       [/x21-/x7E]
   /p{Hankaku}    /pY        [[:hankaku:]]     [/xA1-/xDF]
   /p{Zenkaku}    /pZ        [[:zenkaku:]]     [/x{8140}-/x{FCFC}]
 ( /p{^Zenkaku}   /p^Z       [[:^zenkaku:]]    [/x00-/x7F/xA1-/xDF] )
   /p{X0201}                 [[:x0201:]]       [/x20-/x7F/xA1-/xDF]
   /p{X0208}                 [[:x0208:]]       [/x{8140}-〓∈-∩∧-∃∠-∬Å-¶◯0-9A-Za-zぁ-んァ-ヶΑ-Ωα-ωА-Яа-я─-╂亜-腕弌-熙]
   /p{X0211}                 [[:x0211:]]       [/x00-/x1F]
   /p{JIS}        /pJ        [[:jis:]]         [/p{X0201}/p{X0208}/p{X0211}]
   /p{NEC}        /pN        [[:nec:]]         [/x{8740}-/x{875D}/x{875f}-/x{8775}/x{877E}-/x{879c}/x{ed40}-/x{eeec}/x{eeef}-/x{eefc}]
   /p{IBM}        /pI        [[:ibm:]]         [/x{fa40}-/x{fc4b}]
   /p{Vendor}     /pV        [[:vendor:]]      [/p{NEC}/p{IBM}]
   /p{MSWin}      /pM        [[:mswin:]]       [/p{JIS}/p{Vendor}]
   /p{Halfwidth}             [[:halfwidth:]]   [!#$%&()*+,./0-9:;<=>?@A-Z/[/x5c/]^_`a-z{|}~]
   /p{Fullwidth}  /pF        [[:fullwidth:]]   [!#$%&()*+,./0-9:;<=>?@A-Z[¥]^_`a-z{|} ̄]
   /p{Latin}                 [[:latin:]]       [A-Za-z]
   /p{FullLatin}             [[:fulllatin:]]   [A-Za-z]
   /p{Greek}                 [[:greek:]]       [Α-Ωα-ω]
   /p{Cyrillic}              [[:cyrillic:]]    [А-Яа-я]
   /p{European}   /pE        [[:european:]]    [A-Za-zA-Za-zΑ-Ωα-ωА-Яа-я]
   /p{HalfKana}              [[:halfkana:]]    [ヲ-゚]
   /p{Hiragana}   /pH        [[:hiragana:]]    [ぁ-ん゛゜ゝゞ]
   /p{Katakana}   /pK        [[:katakana:]]    [ァ-ヶーヽヾ]
   /p{FullKana}              [[:fullkana:]]    [ぁ-んァ-ヶ゛゜ーゝゞヽヾ]
   /p{Kana}                  [[:kana:]]        [ヲ-゚ぁ-んァ-ヶ゛゜ーゝゞヽヾ]
   /p{Kanji0}     /p0        [[:kanji0:]]      [〃-〇]
   /p{Kanji1}     /p1        [[:kanji1:]]      [亜-腕]
   /p{Kanji2}     /p2        [[:kanji2:]]      [弌-熙]
   /p{Kanji}                 [[:kanji:]]       [〃-〇亜-腕弌-熙]
   /p{BoxDrawing}            [[:boxdrawing:]]  [─-╂]
  • /p{Halfwidth}は、引用符 ("), アポストロフィー ('), ハイフンマイナス (-) を除くASCII図形文字にマッチします。/p{Fullwidth}は、/p{Halfwidth} に対応する二バイト文字にマッチします。なお、0x5C (/) に対応する/p{Fullwidth}の文字は全角円記号 () であり、0x7E (~) に対応する/p{Fullwidth}の文字は全角マクロン () です。

  • /p{NEC} は、NEC特殊文字とNEC選定IBM拡張文字にマッチします。 /p{IBM} は、IBM拡張文字にマッチします。 /p{Vendor} は、マイクロソフト (Microsoft) CP932のベンダー定義文字にマッチします。つまり、[/p{NEC}/p{IBM}] と等価です。 /p{MSWin} は、マイクロソフト (Microsoft) CP932の文字にマッチします。

  • /p{Kanji0} は、JIS X 4061 の最小漢字文字クラスの文字にマッチします。 /p{Kanji1} は、JIS X 0208 の第一水準漢字にマッチします。 /p{Kanji2} は、JIS X 0208 の第二水準漢字にマッチします。 /p{Kanji} は、JIS X 4061 の基本漢字文字クラスの文字にマッチします。

  • /p{Prop}, /P{^Prop}, [/p{Prop}] などは互いに等価です。この補集合は、/P{Prop}, /p{^Prop}, [/P{Prop}], [^/p{Prop}] などで表すことができます。

  • /pP, /P^P, [/pP] などは互いに等価です。この補集合は、/PP, /p^P, [/PP], [^/pP] などで表すことができます。

  • [[:class:]][^[:^class:]] と等価です。この補集合は、[[:^class:]] または [^[:class:]] です。

  • /p{Prop}, /P{Prop}, [:class:] の表現において、 Prop および class の部分では、大文字/小文字の違いは無視されます。例えば /p{digit}, [:BoxDrawing:] などを用いることもできます。

  • /p{Prop} および /P{Prop} の表現において、接頭辞 Is および In (例えば /p{IsProp}, /P{InProp}, etc.) を任意に付けることができます。しかし接頭辞 Is および In は大文字/小文字の違いを区別しますので、 /p{isProp}, /p{ISProp} などは不可です。

文字クラスの例

漢字
   JIS X 0208:1997の第一・第二水準漢字;    [/x{889F}-/x{9872}/x{989F}-/x{EAA4}]
   JIS X 0213:2004の第三水準漢字;  [/x{879F}-/x{889E}/x{9873}-/x{989E}/x{EAA5}-/x{EFFC}]
   JIS X 0213:2004の第四水準漢字;          [/x{F040}-/x{FCF4}]
   JIS X 0213:2004の第一から第三水準漢字;  [/x{879F}-/x{EFFC}]
   JIS X 0213:2004の第一から第四水準漢字;  [/x{879F}-/x{FCF4}]
   CP-932, NEC選定IBM拡張文字中の漢字;     [/x{ED40}-/x{EEEC}]
   CP-932, IBM拡張文字中の漢字;            [/x{FA5C}-/x{FC4B}]
JIS X 0213:2004
   規定済み;      [/x{8140}-/x{82F9}/x{8340}-/x{84DC}/x{84E5}-/x{84FA}
                   /x{8540}-/x{86F1}/x{86FB}-/x{8776}/x{877E}-/x{878F}
                   /x{8793}/x{8798}/x{8799}/x{879D}-/x{FCF4}]
   空き領域;      [/x{82FA}-/x{82FC}/x{84DD}-/x{84E4}/x{84FB}/x{84FC}
   (残り47字)      /x{86F2}-/x{86FA}/x{8777}-/x{877D}/x{8790}-/x{8792}
                   /x{8794}-/x{8797}/x{879A}-/x{879C}/x{FCF5}-/x{FCFC}]
   規定済み(第一面); [/x{8140}-/x{82F9}/x{8340}-/x{84DC}/x{84E5}-/x{84FA}
                        /x{8540}-/x{86F1}/x{86FB}-/x{8776}/x{877E}-/x{878F}
                        /x{8793}/x{8798}/x{8799}/x{879D}-/x{EFFC}]
   空き領域(第一面); [/x{82FA}-/x{82FC}/x{84DD}-/x{84E4}/x{84FB}/x{84FC}
   (残り39字)           /x{86F2}-/x{86FA}/x{8777}-/x{877D}/x{8790}-/x{8792}
                        /x{8794}-/x{8797}/x{879A}-/x{879C}]
   2004年に追加;  [/x{879F}/x{889E}/x{9873}/x{989E}/x{EAA5}/x{EFF8}-/x{EFFC}]
ユーザ定義文字
   Windows CP-932:   [/x{F040}-/x{F9FC}]
   MacOS Japanese:   [/x{F040}-/x{FCFC}]
丸付き数字
   JIS X 0213の丸1-50;       [/x{8740}-/x{8753}/x{84BF}-/x{84DC}]
   NEC特殊文字の丸1-20;      [/x{8740}-/x{8753}]
   MacOS Japaneseの丸1-20;   [/x{8540}-/x{8553}]
   JIS X 0213の二重丸1-10;   [/x{83D8}-/x{83E1}]
   JIS X 0213の黒丸1-20;     [/x{869F}-/x{86B2}]
   MacOS Japaneseの黒丸1-9;  [/x{857C}-/x{8585}]
ローマ数字
   JIS X 0213の大文字I-XII;         [/x{8754}-/x{875E}/x{8776}]
   NEC特殊文字の大文字I-X;          [/x{8754}-/x{875D}]
   IBM拡張文字の大文字I-X;          [/x{FA4A}-/x{FA53}]
   MacOS Japaneseの大文字I-XV;      [/x{859F}-/x{85AD}]
   JIS X 0213の小文字i-xii;         [/x{86B3}-/x{86BE}]
   NEC選定IBM拡張文字の小文字i-x;   [/x{EEEF}-/x{EEF8}]
   IBM拡張文字の小文字i-x;          [/x{FA40}-/x{FA49}]
   MacOS Japaneseの小文字i-xv;      [/x{85B3}-/x{85C1}]
ASCII図形文字に対応する二バイト文字
   JIS X 0213;      [/x{8149}/x{81AE}/x{8194}/x{8190}/x{8193}/x{8195}/x{81AD}
                     /x{8169}/x{816A}/x{8196}/x{817B}/x{8143}/x{81AF}/x{8144}
                     /x{815E}/x{824F}-/x{8258}/x{8146}/x{8147}/x{8183}/x{8181}
                     /x{8184}/x{8148}/x{8197}/x{8260}-/x{8279}/x{816D}/x{815F}
                     /x{816E}/x{814F}/x{8151}/x{814D}/x{8281}-/x{829A}/x{816F}
                     /x{8162}/x{8170}/x{81B0}]
   Windows CP-932;  [/x{8149}/x{FA57}/x{8194}/x{8190}/x{8193}/x{8195}/x{FA56}
                     /x{8169}/x{816A}/x{8196}/x{817B}/x{8143}/x{817C}/x{8144}
                     /x{815E}/x{824F}-/x{8258}/x{8146}/x{8147}/x{8183}/x{8181}
                     /x{8184}/x{8148}/x{8197}/x{8260}-/x{8279}/x{816D}/x{815F}
                     /x{816E}/x{814F}/x{8151}/x{814D}/x{8281}-/x{829A}/x{816F}
                     /x{8162}/x{8170}/x{8160}]

注: ここでは、ASCIIの0x5Cに対応する文字は逆斜線(または全角逆斜線)であり、 ASCIIの0x7Cに対応する文字はチルド(または全角チルド)です。

正規表現中の埋め込みコード (Perl 5.005 以降)

拡張正規表現 (?{ ... }) または (??{ ... }) は、二バイト文字に特に注意を払わずにパースされます。

セキュリティ上の理由により、(?{ ... }) および (??{ ... }) は関数 match()replace() で使うことができません。

これらは、re() 関数によってPerlにパース可能な正規表現に変換したのち、あなたのコードのスコープの中で正規表現をコンパイルしてください。 use re 'eval'; の宣言が必要になるでしょう。

  use ShiftJIS::Regexp qw(:all);
  use re 'eval';
  $::res = 0;
  $_ = 'ポ' x 8;
  my $regex = re(q/
       /j*?
       (?{ $cnt = 0 })
       (
         ポ (?{ local $cnt = $cnt + 1; })
       )*
       ポポポ
       (?{ $::res = $cnt })
     /, 'x');
  /$regex/;
  print $::res; # 5

埋め込み修飾子

バージョン 0.15 から埋め込み修飾子が拡張されました。

埋め込み修飾子 (?iIjsmxo) は、パターンの先頭にある場合、またはパターンの先頭が ^, /A, /G のいずれかであって埋め込み修飾子がその直後にある場合に限り、本モジュール独自の修飾子 I, j, o を含むことができます。

    e.g. (?sm)pattern  ^(?i)pattern  /G(?j)pattern  /A(?ijo)pattern

Perl 5.005 以前でも、match('エ', '(?i)ト') は正しく偽となります。なぜならこれは match('エ', 'ト', 'i') のように働くからです。

注: 'エ' の第二バイトは 'G' であり、'ト' の第二バイトは 'g' です。

誤マッチを避ける

このモジュールは、置換演算子における修飾子 'e' や while-節によるループをサポートしていません。

これらの機能を利用するには、通常の構文(つまり、組み込みの演算子 m//s///を使用する)を通す必要があります。

一バイト文字が二バイト文字の第二バイトにマッチしたり、二バイト文字が文字境界の前と後の二バイトにマッチしたりといった誤マッチを避けるため、正規表現 '/A(/j*?)' または '/G(/j*?)'を用いることができます。

この場合、'(/j*?)'$1 を対応させ、本来の後方参照は、$2 から始めることを忘れないでください。

例1

    use ShiftJIS::Regexp qw(re);
    $_ = 'あいうえおアイウエオ漢字 シフトJIS';
    my $regex = re('/G(?:/j*?)(/pK)');
    # または my $regex = re('/R{padG}(/pK)');
    while (/$regex/go) {
        print "found a katakana: $1/n";
    }

例2

    use ShiftJIS::Regexp qw(re);
    use ShiftJIS::String qw(strrev); # Shift-JIS版の scalar reverse()
    my $regex = re('/G(/j*?)(/w+)');
    # または my $regex = re('(/R{padG})(/w+)');
    foreach ('s/Perl/Camel/g', '(アイウエオ)AIUEO-漢字') {
        (my $str = $_) =~ s/$regex/$1.strrev($2)/geo; # $1. を付ける
        print "$str/n";
    }

注意: 非常に長い文字列上で検索を行う場合、 /G(/j*?) の代わりに特別な正規表現 /R{padG} を用いるほうが安全と思われます。なぜなら、/R{padG} のほうが * 指定子の繰返し回数が大きくなりにくく、繰返しの上限に達する確率が低くなるからです。


注意事項

このモジュールでは正しい Shift-JIS 文字列の文字は以下の正規表現にマッチしなければなりません。

   [/x00-/x7F/xA1-/xDF]|[/x81-/x9F/xE0-/xFC][/x40-/x7E/x80-/xFC]

外部リソースの文字列は、それが正しい Shift-JIS 文字列であると分かっている場合を除いて ShiftJIS::String モジュールの関数 issjis() を用いて確認すべきです。

正しくない Shift-JIS 文字列を使うと変な結果になることがあります。(正しくない Shift-JIS 文字列を使った場合、どんな結果になるか、何も決まっていませんので、何も期待してはいけません。)

Shift-JIS の二バイト文字の中には、第二バイトが [/x40-/x7E]、すなわち

   @ABCDEFGHIJKLMNOPQRSTUVWXYZ[/]^_`abcdefghijklmnopqrstuvwxyz{|}~

であるものがあります。

Perl の構文解析では、このようなバイトについて特別な処理はされていませんので、問題が発生することがあります。例えば、リテラル "表" は致命的エラーを引き起こします。なぜなら、第二バイトの 0x5C が閉じクォートをエスケープするからです。

外部のファイル等から読み出した場合は、この問題は起こりませんが、スクリプトを Shift-JIS で書く時には十分な注意が必要です。

Shift-JISのリテラル文字列を作るためには、シングルクォート風のヒアドク(<< '')や、メタ文字 /xhh を使うほうがよいでしょう。

Shift-JIS の第二バイトに出て来ないASCII図形文字([/x21-/x3F])は以下の通り。

   !"#$%&'()*+,-./0123456789:;<=>?

クォート風演算子のデリミタとしては、これを使うとよいかもしれません。


既知のバグ

  • メタ文字 /U, /L, /Q, /E および変数展開は考慮されておりません。必要なら、"" (or qq//) 演算子を使ってください。

  • 単語境界を扱うメタ文字 /b および /B は正しく動作しません。

  • 修飾子 i, I および j は、/p{}, /P{}, POSIX [: :]. (例えば /p{IsLower}, [:lower:] など) には作用しません。そのため、re('/p{Lower}', 'iI') の代わりに re('/p{Alpha}') を使用してください。

  • 後読み言明 (例えば (?<=[A-Z])) が直前の二バイト文字の第二バイトに誤ってマッチすることには対処されていません。例えば、 match("アイウ", '(?<=[A-Z])(/p{Kana})')('イ') を返しますが、もちろん誤りです。

  • 控えめな量指定子を含むパターン (例えば .??/d*?) は、空文字列とマッチすることができますが、jsplit() のパターンとして用いた場合、組み込みの split() から予想される動作と異なることがあります。


著者

SADAHIRO Tomoyuki <SADAHIRO@cpan.org> 貞廣 知行

  Copyright(C) 2001-2007, SADAHIRO Tomoyuki. Japan. All rights reserved.
  This module is free software; you can redistribute it
  and/or modify it under the same terms as Perl itself.


関連モジュール

the ShiftJIS::String manpage
the ShiftJIS::Collate manpage
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值