Perl の正規表現での \A と \Z の扱い


公開 (UL): 2023-09-15
更新 (UD): 2023-09-15
閲覧 (DL): 2026-04-06

この記事のもくじ

→本文へ
当サイトは SNS の公式アカウントがないので,「議論ネタ」にする際は,皆さんのブログ,メーリングリスト,SNS や掲示板などで,適当にハッシュタグを付けたりリンクを掲載するなどしてご利用ください。

前の記事

2023-01-16
Android のキーボード・ショートカット一覧

次の記事

2024-02-11
XMPP - 長く使える安心チャット

最近の記事

2022-08-09
代表的な画像ファイル形式一覧
2022-04-04
サイトのローカル試験と実ウェブ上の差を縮める手法(Perl)
2021-12-17
Perl で利用宣言時にモジュールをカスタマイズする
2021-06-01
Base54
2021-06-01
PPOP
新着情報
She appears also the top page.

新着情報 Recent docs.

Sorry, but most of these pages are only Japanese.
現場で活きる「電子工作」 «Get starting electronics handmaking!»
政権政党圧勝により介護福祉制度の改悪は必至! 現場の自助・自衛のための機器「手作り」入門!

人気記事 Frequent view pages.

おすすめ! Recommend

ご連絡 Contact

▼ メールフォームはこちら
SSL 証明書の更新に不具合が多いため,期限切れエラーが出た際は,お手数ですが「例外指定」をお願いいたします。

ファイルの暗号化
当サイト管理者(石川)宛にメール添付で送信するファイルを暗号化したい時は,唯一のパスワードを PPOP で取得できます。 PPOP gives a password for encryption of the file(s) attached your mail to the admini­strator of this site M.Ishikawa.
PPOP

MEMO / Email to the Author
あとで調べたい点のメモなどに利用可能。
下部ボタンでそのまま著者にメールできます。


CAPTCHA: easy math prob in Japanese

時事川柳 News Senryu

颯爽と  
アソー出てきて
  轍を踏む
Aso will finish the government of LDP also this time.

以前もこの方が(げや→)下野に導いたんでしょって。

(⌚2025-10-12)

ご支援 Support this site.

まだまだ コロナ失業中!!
CORONA-NEET, seeking works now!

この活動をご支援いただける方はこちらへ Could you support this site, see here (but Japanese).
都道府県庁さん, 地方自治体さんや教育委員会さん, 障害者就労支援機関さんやその他公的機関,省官庁さん, 「タダ見」しているだけでは, 格差が広がるだけだと思いませんか?
Welcome!
Alibaba    Google
The companies, thanks for many accesses every months! Are the articles I wrote helping for increasing your income? Although, I cannot get even a penny and jobs from that.

 よくウェブで見かける説明はこんな感じ。

\A は行頭に,\Z は行末にマッチする。

 ところが,取扱いはそう一筋縄でもなさそうなのよね。ちょっと突っ込んでみたい。

● 「文字」として扱われない

 フォームやクエリーで送られてきたデータの中から,特定フィールドだけ取り出したり,あるいは削除したい場合,生データに直接的に操作できれば簡単だと思った。たとえば,生データに近い形式で保存を考えた時,パスワードのフィールドとして pw と pwv の2つがあって,pwv 側は確認用で保存の必要はないから削除したいような時,当初は以下のようなものを考えた。

▼ うまくいかない例(NG)
   $fields; # query (GET) or form (POST) data
   $fields =~ s/[\A&]pwv=.*?[\Z&]/&/;
   $fields; # ← deleted "pwv" field ? (fail)

 ちなみに,“*?”ってのは「最短マッチ」のことで,任意文字で任意文字数にマッチさせた場合,次のフィールドとの境界(つまり最短の)& を任意文字“.”へのマッチから外すためのもの。
  pwv フィールドが先頭にあれば \A にマッチし,次のフィールドとの境界の & までを消去し,また,最後のフィールドとしてあれば,最後にある & で区切られた部分から末尾(\Z)までを消去すればいい……と,思ってこうしたが,これではうまくいかない。「\A(\Z)がこんなところにあってはダメ」的なエラーが出る。なぜ?
 どうやら「文字クラス」([] で括った文字のどれか)として扱ってくれないよう。たとえば「削除」ではなく,単純に1つのフィールドの設定値を取り出したいだけなら,単純なマッチ式で以下のようにするとうまくいく。

▼ フィールドの取り出し(OK)
   $fields =~ /(\A|&)pwv=(.*?)(\Z|&)/;
   $2; # ← value of the "pwv" field

 これだと,最初か最後にあってもマッチする。「文字として」よりも「文字列」的に扱えばよかったみたい。
 ただ,設定値取り出しは上記でいいが,削除だと別の点で問題が起きた。これを「削除」したい時はこうすればよさそうな気がするが……。

▼ もうひといきの例(NG)
   $fields =~ s/(\A|&)pwv=.*?(\Z|&)/&/;
   $fields; # ← deleted "pwv" field ? (just a little fail)

 置換文字側の & というのは,pwv フィールドが中間にある時にそこを削除して & 1個に置換し,前後のフィールドを詰めるものだが,先頭か末尾にある時は & に置換する必要はない。つまり,端にある時と中間にある時で置換内容の有無を変えないとダメっぽい。で,考えたのがコレ。

▼ なんとかうまくいく例(OK)
   $fields =~ s/(\A|&)pwv=.*?(\Z|&)/"$1$2"eq"&&"?"&":""/e;

 スイッチの“e”ってのは,置換文字側が「式」であることを意味するもの。つまり,フィールドの前と後ろの両方に & がある時だけ & 1個に置換し,端にある時は単純に消去するだけってこと。

◆ 複数の時はさらに工夫が必要

 じつはこの時は,消去したいフィールドが pwv のほかにもあって,それも一緒に消したいと思っていた。たとえばそれが,一時的に使ったセッション ID の sid だった場合,次のようにすればうまくいきそうな気がする。

▼ ダメな例(NG)
   $fields =~ s/(\A|&)(pwv|sid)=.*?(\Z|&)/"$1$3"eq"&&"?"&":""/eg;
   $fields; # ← deleted "pwv" and "sid" fields ? (fail)

 “g”スイッチを付けたから両方置換してくれるかというと,うまくいかないケースがある。それは,この pwv と sid のフィールドが隣り合っていた場合で,前側しか消去されない。前にあるフィールドで置換が起きると,その直後の文字から次のマッチ部分を探すことになるが,置換した前部分は & や \A のマッチ対象から外されるらしい。
 どうすればいいかというと,たとえばこう。

▼ うまくいく例(OK)
   while( $fields =~ s/(\A|&)(pwv|sid)=.*?(\Z|&)/"$1$3"eq"&&"?"&":""/e ){}
   $fields; # ← deleted "pwv" and "sid" fields (OK)

 つまり,マッチするものがなくなるまで全体を繰り返して置換対象にする。ただ,正規表現マッチングの「繰り返し」って,ワリと負担なのよねぇ……。と言っても,この場合ではせいぜい2回だが。削除したいフィールドが多数ある時は,1文で書ける点は便利ではないかと思う。
 単語境界を示す“\b”が使えるなら while は不要になりそうだが,& 以外にもマッチしてしまうので,たとえば他フィールドの「値」の側にたまたま“-pwv=”なんて文字列があるとアウトよね。
 これは,整数の3桁ごとにコンマを挿入するつぎのやり方の応用。

▼ 3桁ごとにコンマ
   $integer = 整数; # Insert commas each 3 digits
   while( $integer =~ s/(\d)(\d\d\d)\b/$1,$2/ ){}

 この場合も“g”スイッチを付けてもダメで,while 文の中に入れて繰り返す必要がある。1の位を含む後ろの桁からマッチする箇所を探すから,桁が多いとコンマを入れる場所を前に戻って探す必要が生じる。で,繰り返しが必要になるわけだ。
 でもまぁ,C言語みたいに,文字列化して数字がいくつ並んでいるか数えて……なんてコード書くよりはラクだよね。

● おわりに

 正規表現って便利だわー。筆者はこれを応用して,ダウンロードした他サイトの HTML から,正規表現で必要な部分だけ抜き出して見たりしている。追加で読み込むスクリプト,広告や他記事の紹介など,余計な部分はみんな切り落とすから,読み込みも表示も早くて助かる。
 でも,そういった方法を使いこなせるのは一部の人間なのだろうね。だから,社会全体としては,筆者の想像よりもスゴく面倒な手法を使って余計な時間を費やしているんじゃないかって気がする,今日この頃。と言っても,その手のものも含めて,今のところ(2023,9 月)筆者の元に仕事の話なんか来ないけどね。



© M.Ishikawa; TREEWARE 2026.