正規表現の呪縛?No.04252
CXYZ さん 04/04/08 18:26
 
 マクロ作者の皆さん今晩は。別フォーラムにはちょこちょこ登場するCXYZです。
 思い立ってマクロの勉強を始めたのですが、正規表現に関して自分ではどうし
てもわからなくなってしまい、皆様のお知恵を拝借したく投稿させていただきま
した。

 私は、メール内の広告を検索するマクロ(行く行くはその部分を削除させた
い)を作成し、なんとか動くようなものを作ることができました。それに際し、
広告の上の部分でよく見かける「いろいろな文字列+pr」や「いろいろな文字
列+ad」を検索するため、秀丸Q&Aで正規表現を勉強しました。
 そして、まだまだ不十分ではあるものの、以下のような表現を使って、少なく
とも半分以上の確率で、広告の先頭部分にヒットさせています。

^[^/:A-Za-z0-9ぁ-んァ-ヶ〔漢字全て〕]+[(pr)(ad)]+[^/:A-Za-z0-9ぁ-んァ-ヶ
〔漢字全て〕]+
 (行頭が英数字・平仮名・片仮名・漢字以外の文字列の繰り返しである。その
後に pr あるいは ad の2文字が1度以上出現する。その後に、再び英数字や漢字
(先ほどと同じ)以外の文字列が1度以上存在する。

 そして、この表現の確実さをより高めるため、いろいろな広告を試しました。
しかし、それほどたくさんのパターンを潜り抜ける前に、早速問題が発生しまし
た。マクロが次の文字列を広告と偽ってきたのです。
 「 (><)/【ちょっとお知らせ】」

 「これは明らかにおかしい。この(正規)表現のどこにそんな文字列を大勝と
する部分があるんだ?」そう思い、何度もQ&Aを見直しました。それから40分ぐ
らい悩んだ末、ようやく結論が出たのです。
 答えは以下の1文にありました。
 「あ、そうそう。メタキャラクタはキャラクタクラス指定の中では (エスケー
プキャラクタを前に置かなくても自動的に)その特殊な意味を失って、単にその
文字自身を表わすようになります。」

 これを読んだ私は、一瞬霧が晴れたような爽快な気分になったのですが、直ぐ
に別の疑問がもやもやと湧いてきました。「それじゃあ、キャラクタクラス指定
の中でグルーピング指定するにはどうしたらいいんだろう…。」

 もちろん、考えれば他の方法もあるとは思いますが、とりあえずは
 「キャラクタクラス内だからといって、エスケープもしないのに勝手に通常の
文字になってもらっては困る」
のです。何かしら
 「キャラクタクラス内でグルーピング先頭を示すための逃げ道」
があるとは思うのですが、それがどうしてもわかりません。もしや、このような
ことはできないのでしょうか。それとも、単なるこちらの見落としでしょうか。
 マクロではなく、完全に正規表現だけの質問になってしまいましたが、ご指導
いただければ幸いです。

 P.S. 〔漢字全て〕の部分にはJIS範囲外のものも含まれていますが、今回はそ
ちらがメインではなかったので置き換えさせていただきました。(念のため)

[ ]
RE:04252 正規表現の呪縛?No.04253
Iranoan さん 04/04/08 19:05
 
 CXYZ さん今日は、Iranoan です。
>  「キャラクタクラス内でグルーピング先頭を示すための逃げ道」
> があるとは思うのです
 これは無かったと思います。
 しかし
> 行頭が英数字・平仮名・片仮名・漢字以外の文字列の繰り返しである。その
> 後に pr あるいは ad の2文字が1度以上出現する。その後に、再び英数字や漢字
> (先ほどと同じ)以外の文字列が1度以上存在する。
を実現したければ、それは必要ありません。
^[^/:A-Za-z0-9ぁ-んァ-ヶ亜-\xFC\x4B]+(pr|ad)+[^/:A-Za-z0-9ぁ-んァ-ヶ亜-\xFC\
x4B]+
というように、単純にパターンのグループ化を使えばよいです。

※「\xFC\x4B」は「黒」の異字体の代わりです。

[ ]
RE:04253 正規表現の呪縛?No.04254
CXYZ さん 04/04/08 21:01
 
Iranoanさん今晩は、CXYZです。
>  これは無かったと思います。
 そうなんですか、以外です。
>  しかし
> > 行頭が英数字・平仮名・片仮名・漢字以外の文字列の繰り返しである。その
> > 後に pr あるいは ad の2文字が1度以上出現する。その後に、再び英数字や漢字
> > (先ほどと同じ)以外の文字列が1度以上存在する。
> を実現したければ、それは必要ありません。
> ^[^/:A-Za-z0-9ぁ-んァ-ヶ亜-\xFC\x4B]+(pr|ad)+[^/:A-Za-z0-9ぁ-んァ-ヶ亜-\xFC\
> x4B]+
> というように、単純にパターンのグループ化を使えばよいです。
 あわっ、わらばばああぁ!その方法がありましたね、全く気づきませんでした。
もっと単純に考えればよかったんですね。とっても勉強になりました。
 更に、
> ※「\xFC\x4B」は「黒」の異字体の代わりです。
 こういう書き方をすればよかったんですね。実は、\を使って漢字を表現する
方法がいまいち分かっておらず、それを使った正規表現やメッセージも操ること
ができずにいました。(たとえば、全角スペースを\x8140とするなど)
 これでやっと、一通りマクロが理解(だけは)できたような気がします。これ
からもっと修練を積んで、最終的にはライブラリに公開できるようなものが書き
たいです。
 本当にすっきりしました。いつもながらのすばやい返信、どうもありがとうご
ざいました。

## でも、黙ってエスケープされるのってやっぱり気持ち悪いなあ。

[ ]
RE:04253 正規表現の呪縛?No.04255
アルビレオ さん 04/04/08 21:38
 
アルビレオです。

めんどうなので、以下は「英数字・平仮名・片仮名・漢字以外」を「記号」と呼
ぶことにします。

>^[^/:A-Za-z0-9ぁ-んァ-ヶ亜-\xFC\x4B]+(pr|ad)+[^/:A-Za-z0-9ぁ-んァ-ヶ亜-\xFC
>\x4B]+

これだと、記号と記号の間に pr か ad 以外の文字があるとマッチしませんよね。

^[^/:A-Za-z0-9ぁ-んァ-ヶ亜-\xFC\x4B]+.*(pr|ad).*[^/:A-Za-z0-9ぁ-んァ-ヶ亜-\x
FC\x4B]+

とした方がいいと思います。

CXYZ さん
>黙ってエスケープされるのってやっぱり気持ち悪いなあ。

まず[]で囲まれたグループは、扱い上は「1文字」になります。
文字の種類を限定した . だといってもいいですね。
1文字でしかないため、正規表現での特別な記号は無意味になります。
(わかりにくいですが、本当に無意味なんです)

そして[]の外では .*+? などの記号は特別な意味を持ってしまうために、その文
字自身を表すには \ でエスケープする必要があります。

つまり[]の中が黙ってエスケープしているわけではなく、[]の外側の方が記号を
書くためにはエスケープが必要な特殊な世界になっているのです。
逆に[]の中では ^-] が特別な記号として[]の外側とはまったく違う意味を持ち
ます。

という説明で納得できるでしょうか?

[ ]
RE:04255 正規表現の呪縛?No.04256
CXYZ さん 04/04/08 22:10
 
アルビレオさん今晩は、CXYZです。
 ご提案&ご説明ありがとうございます。

> …これだと、記号と記号の間に pr か ad 以外の文字があるとマッチしませんよね。
 そういえばそうですね。今まで引っ掛けられなかったときは、確かに全て原因
がここにあったような気がします。
>
> ^[^/:A-Za-z0-9ぁ-んァ-ヶ亜-\xFC\x4B]+.*(pr|ad).*[^/:A-Za-z0-9ぁ-んァ-ヶ亜-\x
> FC\x4B]+
>
> とした方がいいと思います。
 早速そのようにいたしました。ううん、これも思いつきませんでした。

> まず[]で囲まれたグループは、扱い上は「1文字」になります。
 念のために確認させていただきたいのですが、これは「グループ内の文字がそ
れぞれ単独の文字として扱われる」ということでよろしいでしょうか。
> 文字の種類を限定した . だといってもいいですね。
 なるほど。
> 1文字でしかないため、正規表現での特別な記号は無意味になります。
> (わかりにくいですが、本当に無意味なんです)
 上記の私の解釈が合っているとすれば、分かったような気がします。
>
> …という説明で納得できるでしょうか?
 分かりました。私のグループ内外でのエスケープに対する解釈が、全く逆だっ
たということですね。
 どんどん霧が晴れていきます、私の理解が間違っていなければですが。丁寧な
ご説明ありがとうございます。今、とっても楽しいです。

[ ]
RE:04256 正規表現の呪縛?No.04257
Iranoan さん 04/04/09 11:59
 
 CXYZ さん、アルビレオさん今日は、Iranoan です。
> > …これだと、記号と記号の間に pr か ad 以外の文字があるとマッチしませんよ
>ね。
>  そういえばそうですね。今まで引っ掛けられなかったときは、確かに全て原因
> がここにあったような気がします。
 元々の投稿で、
>  私は、メール内の広告を検索するマクロ(行く行くはその部分を削除させた
> い)を作成
ということなので、そういった文字列、私の手元にある ML を例とすると、
--+ PR +--------------------------------------------------------------
--------------------------------------------------------------【AD】---
といった文字列を検索したいのではないでしょうか? それならば、PR や AD
が存在していない文字列は、マッチしてはいけないと思います。つまり
> > ^[^/:A-Za-z0-9ぁ-んァ-ヶ亜-\xFC\x4B]+.*(pr|ad).*[^/:A-Za-z0-9ぁ-んァ-ヶ
>亜-\x
> > FC\x4B]+
とすると、仮に
--------------------------------------------------------------------
pr と ad を両方同時に検索させるには、正規表現
(ワイルドカードを拡張したようなもの) を使って (pr|ad) とします。
--------------------------------------------------------------------
という文章があると、2 行目にマッチしまいますが、これは良くないと...。

[ ]
RE:04257 正規表現の呪縛?No.04258
CXYZ さん 04/04/09 18:14
 
Iranoanさん・アルビレオさん今晩は、お世話になっていますCXYZです。
 やはり勉強不足な感が否めませんがこれからしっかり足りない部分を補ってい
こうと思います。

    Iranoanさんへ
> ………
> --+ PR +--------------------------------------------------------------
> --------------------------------------------------------------【AD】---
> といった文字列を検索したいのではないでしょうか? それならば、PR や AD
> が存在していない文字列は、マッチしてはいけないと思います。つまり
> > > ^[^/:A-Za-z0-9ぁ-んァ-ヶ亜-\xFC\x4B]+.*(pr|ad).*[^/:A-Za-z0-9ぁ-んァ-ヶ
> >亜-\x
> > > FC\x4B]+
> とすると、仮に
> --------------------------------------------------------------------
> pr と ad を両方同時に検索させるには、正規表現
> (ワイルドカードを拡張したようなもの) を使って (pr|ad) とします。
> --------------------------------------------------------------------
> という文章があると、2 行目にマッチしまいますが、これは良くないと...。
 おっしゃるとおりまずいです。私も数回試してそれに気づいたので、

    アルビレオさんへ
 前回の投稿後、また元に戻してしまいました。せっかくご提示いただいたのに
申し訳ないです。そもそも、私の文字の絞り込み方が甘いんだと思っています。
これについてはもっと研究してみます。

[ ]