• ベストアンサー

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

Perlの正規表現で質問です。 複数種類の括弧、たとえば()、【】、[]などで囲まれていない文字をマッチングさせたいのです。 括弧は1行に複数ある可能性があり、ない場合もあります。 (abc)【def】ghi【jkl】 だとghiの部分。 【abc】【def】(ghi)jkl(mno) だとjklです。 頭に必ず括弧が来たり、括弧が一回だけなら括弧閉じるの種類をor検索ではじけるのですが、何回くるかわからないのでどうしたらいいか困っています。 方法がありましたら教えてください。

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

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

こういうやり方はどうでしょうか? 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

tukikageran
質問者

お礼

ありがとうございます。 実はCGIで全角交じりの文字列を検索するのが目的の使い方なのですが、教えていただいた方法ですと一部文字化けが起きるようです。 もしよろしければ全角にも対応した方法を教えていただけませんでしょうか。 検索対象 $word = "【社内文書】 (08年度) プロジェクト○○企画書090111(第三営業部用).doc" かつスペースを排除したいと思っています。 よろしくお願いいたします。

その他の回答 (4)

  • ruri6syo
  • ベストアンサー率42% (9/21)
回答No.5

すみません。#4です。 >ただ、tr///dの間に全角の<>を設定文字化けを起こすようです。 タイプミスで意味不明になりました。 正しくは、 ただ、tr///dの間に全角の<>を設定すると、文字化けを起こすようです。 です。失礼しました。 ついでの補足として、今回テストしたコードでは結局$wordに文字列を設定して処理させているのですが、 当初は#3の御方がなさっているようにファイルから一行ずつ読み込む想定でしたので、最後配列 @nokori に入れ込んでおります。

  • ruri6syo
  • ベストアンサー率42% (9/21)
回答No.4

Perlの初心者なので、よくわからないですが、括弧をマッチングさせ削除した残りを抽出する方法ではだめなのですか? $word = '【社内文書】(08年度) プロジェクト○○企画書090111(第三営業部用).doc'; $word =~ tr/([])()[]【】 //d; push(@nokori,$word); print @nokori; _END_ テストした所、文字化けは起こりませんでした。(スペースも外せています) ただ、tr///dの間に全角の<>を設定文字化けを起こすようです。 最終的にどのようなプログラムなのか分からないので、この方法が良いのかどうかはわかりませんが、とにかく括弧とスペースがはずせます。

tukikageran
質問者

お礼

ありがとうございました。 試してみましたけど、これは括弧をはずすだけで括弧に囲まれた文字も抽出してしまいますよね? 今回の目的としては括弧に囲まれてる部分の文字は対象外としたかったのでせっかく教えていただきましたが要件は満たせてないようです。 申し訳ありません。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.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)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

>もしよろしければ全角にも対応した方法を教えていただけませんでしょうか。 対応してますけど。 ただしきちんと入力を適切に decode してやれば。ですが。 お使いのPerlが5.8以降のものなら、入力をdecodeしてください。 5.6以前ならご愁傷様。

tukikageran
質問者

お礼

ありがとうございました。 お礼が遅れましてすみません。 バージョン調べてみたら5.6でした。 5.10が最新のようなので入れ替えを検討いたします。

関連するQ&A