みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

複数種類の括弧でくくられてない文字をマッチングさせたい

Perlの正規表現で質問です。
複数種類の括弧、たとえば()、【】、[]などで囲まれていない文字をマッチングさせたいのです。

括弧は1行に複数ある可能性があり、ない場合もあります。

(abc)【def】ghi【jkl】
だとghiの部分。
【abc】【def】(ghi)jkl(mno)
だとjklです。

頭に必ず括弧が来たり、括弧が一回だけなら括弧閉じるの種類をor検索ではじけるのですが、何回くるかわからないのでどうしたらいいか困っています。

方法がありましたら教えてください。

投稿日時 - 2009-01-17 10:47:00

QNo.4636836

困ってます

質問者が選んだベストアンサー

こういうやり方はどうでしょうか?

use strict;
use warnings;
use feature 'say';

use utf8;

binmode STDOUT, ':encoding(cp932)';

my $open = quotemeta "([【";
my $close = quotemeta ")]】";

while (my $line = <DATA>) {
chomp $line;
my @f = $line =~ m{(?:\A|[$close]) ([^$open]+) }xg ;
say join ' : ', @f;
}
__END__
(abc)【def】ghi【jkl】
(abc)【def】ghi【jkl】mno
【abc】【def】(ghi)jkl(mno)
xyz【abc】【def】(ghi)jkl(mno)

結果:
ghi
ghi : mno
jkl
xyz : jkl

投稿日時 - 2009-01-17 15:42:57

お礼

ありがとうございます。
実はCGIで全角交じりの文字列を検索するのが目的の使い方なのですが、教えていただいた方法ですと一部文字化けが起きるようです。
もしよろしければ全角にも対応した方法を教えていただけませんでしょうか。

検索対象
$word = "【社内文書】 (08年度) プロジェクト○○企画書090111(第三営業部用).doc"

かつスペースを排除したいと思っています。
よろしくお願いいたします。

投稿日時 - 2009-01-17 16:55:31

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.5

すみません。#4です。

>ただ、tr///dの間に全角の<>を設定文字化けを起こすようです。

タイプミスで意味不明になりました。
正しくは、

ただ、tr///dの間に全角の<>を設定すると、文字化けを起こすようです。

です。失礼しました。
ついでの補足として、今回テストしたコードでは結局$wordに文字列を設定して処理させているのですが、
当初は#3の御方がなさっているようにファイルから一行ずつ読み込む想定でしたので、最後配列 @nokori に入れ込んでおります。

投稿日時 - 2009-01-23 21:13:42

ANo.4

Perlの初心者なので、よくわからないですが、括弧をマッチングさせ削除した残りを抽出する方法ではだめなのですか?

$word = '【社内文書】(08年度) プロジェクト○○企画書090111(第三営業部用).doc';
$word =~ tr/([])()[]【】 //d;
push(@nokori,$word);
print @nokori;

_END_

テストした所、文字化けは起こりませんでした。(スペースも外せています)
ただ、tr///dの間に全角の<>を設定文字化けを起こすようです。
最終的にどのようなプログラムなのか分からないので、この方法が良いのかどうかはわかりませんが、とにかく括弧とスペースがはずせます。

投稿日時 - 2009-01-23 21:04:56

お礼

ありがとうございました。
試してみましたけど、これは括弧をはずすだけで括弧に囲まれた文字も抽出してしまいますよね?

今回の目的としては括弧に囲まれてる部分の文字は対象外としたかったのでせっかく教えていただきましたが要件は満たせてないようです。

申し訳ありません。

投稿日時 - 2009-01-25 19:03:05

ANo.3

マルチバイト文字の境界をまたいだ間違ったマッチには対処していません。

use strict;
use warnings;
use feature 'say';

#use utf8;
#binmode STDOUT, ':encoding(cp932)';

my $open1 = quotemeta "([";
my $open2 = quotemeta "【";
my $close1 = quotemeta ")]";
my $close2 = quotemeta "】";

while (my $line = <DATA>) {
chomp $line;
#my @f = $line =~ m{(?:\A|[$close1]) ([^$open1]+) }xg ;
my @f = $line =~ m{(?:\A|[$close1]|$close2) (.*?) (?:[$open1]|$open2|$)}xg ;
say join ' : ', grep /./, @f;
}
__END__
(abc)【def】ghi【jkl】
(abc)【def】ghi【jkl】mno
【abc】【def】(ghi)jkl(mno)
xyz【abc】【def】(ghi)jkl(mno)

投稿日時 - 2009-01-17 18:35:25

ANo.2

>もしよろしければ全角にも対応した方法を教えていただけませんでしょうか。

対応してますけど。
ただしきちんと入力を適切に decode してやれば。ですが。

お使いのPerlが5.8以降のものなら、入力をdecodeしてください。
5.6以前ならご愁傷様。

投稿日時 - 2009-01-17 17:27:19

お礼

ありがとうございました。
お礼が遅れましてすみません。
バージョン調べてみたら5.6でした。

5.10が最新のようなので入れ替えを検討いたします。

投稿日時 - 2009-01-25 19:00:36

あなたにオススメの質問