- ベストアンサー
正規表現で文字クラスの引き算
- 正規表現の文字クラスについてお聞きします。
- [0-6]の中から3~5を除いた指定方法について、Perlと.NETの違いを教えてください。
- Perlにおいても同じような引き算の指定方法はあるのでしょうか。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
.NET 正規表現とは違ったアプローチになりますが、一応あることはあります。 (.NET 正規表現互換も、package Something; use overload; sub import { overload::constant qr => \&substraction } sub substraction { #... } みたいなことをすればできるかもしれませんが――私はよく知りません) 本題に戻りますが、Unicode ブロック属性を用いれば目的は果たせると思います。 例えば: use utf8; print 1 if 'あ' =~ /\p{InHiragana}/; このように、\p{InHOGE} という形の文字クラス (と呼ぶのでしょうか) が utf8 プラグマの機能として (自信なし) 用意されています。 ちなみに、CJK 統合漢字の属性は \p{InCJKUnifiedIdeographs} だったと思います。 さらにこの属性を自分で作ることもでき: sub InKana { return <<'EOF'; +utf8::InHiragana +utf8::InKatakana EOF } まあこんな感じで、+ から始まる属性は追加、- から始まるやつは削除という風に定義できるらしいです。 応用すれば CJK から J を引いたクラスも作れると思います。 文字のバイト列を調べて平仮名かどうか調べる――といったテクニックの現代版と言えるのでしょうか。分かりません。 `perldoc perlunicode' で more details を得ることができると思います。 なお、この回答は全般的に「自信なし」です。
その他の回答 (2)
- pick52
- ベストアンサー率35% (166/466)
0~2と6なら [0-26] と書きます。 > Perl が機能の豊富さで他の言語に負けるのはめずらしいケースなので、 そもそも、Perlは正規表現を実装している言語の中では古い方です。 現在、正規表現に対応している言語の大半はPerlの正規表現を参考に 作られています。 (そのため、Perlの正規表現互換の記述である場合が多いです) 一方で、古いために新しい要求などがでてきても仕様が古いために 対応されていません。 新しい言語ではその辺を独自に改良している場合があります。 しかし、お書きになっているような書き方よりPerlのような書き方の 方がずっと簡単でシンプルだと思いますが...。
お礼
ありがとうございます。 たぶん見方が違うんだと思うんですが、Perl の正規表現はだらしないほど拡張しまくっているように思えます。 たとえば (?<=PATTERN) のような文字を消費しないパターンとか、パターンを再帰させてカッコの対応にマッチさせるようなのは、昔なかったような? 気がします。 とまれ、確かに、上の書き方はシンプルではありませんね。 状況を説明すると、.NET と Perl で同じ処理を書いていて、.NET で書いた人がくれたパターンが Perl で動かなかったという感じです。 マーその作業の体制が???という話はあるんですが・・・(^^;
- 9arabi
- ベストアンサー率32% (140/433)
perlではそのような記述はしないと思いますが [0126789]という書き方ではダメなのですか? (質問の趣旨とずれていたらすみません)
補足
ありがとうございます。 たとえば「CJK統合漢字全体から日本語で使う漢字を除いた残り」 (日本では使わない漢字) と言う風に、上の 0-9 にあたる文字セットも 3-5 に当たる文字セットも膨大なケースを想定しています。 Perl が機能の豊富さで他の言語に負けるのはめずらしいケースなので、 質問しました。。。
お礼
ありましたね、文字プロパティのユーザー定義! これで行けると思います。 #! perl # regtest.pl -- 正規表現のテスト while(<DATA>) { chomp; print "$_ matches /\\p\{p01256\}/\n" if /\p{p01256}/; } sub p01256 { return<<'EOF'; +0030 0036 -0033 0034 EOF } __DATA__ 0 1 2 3 4 5 6 7 8 9 => 0 matches /\p{p01256}/ 1 matches /\p{p01256}/ 2 matches /\p{p01256}/ 5 matches /\p{p01256}/ 6 matches /\p{p01256}/ でバッチリです。 どうもありがとうございます!
補足
下のお礼の続きです。 文字プロパティが定義できることは知ってたんですが、マイナスで削除できるところは知りませんでした。 ややこしいですが便利ですね。 本当にありがとうございます。