- ベストアンサー
正規表現中の()について
正規表現中の()について 繰り返し正規表現を行い、マッチ部分を配列に入れる場合の疑問です。 今回、while文を使わずに書いてみようとしています。 #3個以上数字が連続していたら、配列へ入れる。…(1) my @data = ( $str =~ /\d{3,}/g ); #3個以上連続している、同じ文字を取り出して、配列へ入れる。…(2) my @data = ( $str =~ /(.)\1{2,}/g ); 1つめのほうは期待通りに動きました。 が、2つめは正規表現内の()で囲まれた範囲しか、配列に入ってくれませんでした…。 具体的には、$str='AAABBB'なら、 @data='A','B'になってしまいました。(AAA,BBBを配列に入れたい) たぶん、while文と$&を使えば書けそうだとは思いますが、 今回は、この書式で期待通りに動かす方法を知りたいです。 AAA,BBBを配列に入れるにはどのように書けばよいでしょうか? どうか、ご教授ください。 よろしくお願いします。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
さらにおまけですが, 思わず split を使ってしまったものの意味としては substr を使うべきだよなぁとちょっと反省. あと, 質問をよく見たら「3個以上」なのでそれもあわせると my @data = ($str =~ /(.{3,})(?(?{$1 eq substr($1, 0, 1) x length($1)})|(?!))/g); という感じかな. いずれにしても, この 1文だけではあとで見た人が泣きそうだと思う.
その他の回答 (5)
- Tacosan
- ベストアンサー率23% (3656/15482)
あ, 閉じかっこを 1つ忘れた. my @data = ($str =~ /(..+)(?(?{$1 eq (split '', $1)[0] x length($1)})|(?!))/g); だ.
- Tacosan
- ベストアンサー率23% (3656/15482)
ふと思いついたことをやってみたらできてしまった.... my @data = ($str =~ /(..+)(?(?{$1 eq (split '', $1)[0] x length($1)})|(?!)/g); Perl 5.6 以上ならできると思うけど, たぶんよい子は真似しちゃだめだろうとも思う.
- Tacosan
- ベストアンサー率23% (3656/15482)
#2 に一票. 「後で使う」ためには何らかの方法でキャプチャしなければならず, そうすると $なんちゃら に値が入ってしまうので得られる配列にも余計なものが含まれてしまいます. たぶん g で一気にというのは無理じゃないかなぁ....
- notnot
- ベストアンサー率47% (4900/10358)
無理じゃないかと思います。 「同じ文字」ということを使うためのカッコ、結果を取り出す範囲指定のカッコをそれぞれ指定しないといけないので、カッコは二組必要になり、 my @data = ( 'AAABBB' =~ /((.)\2{2,})/g ); とすると、@data ← ( 'AAA', 'A', 'BBB', 'B' ) となるので、その偶数番目の要素だけを使うくらいでしょうか。 =~ 演算子以外も使って良ければ、 my @data = grep /../, ( 'AAABBB' =~ /((.)\2{2,})/g );
お礼
なるほど、参考になります。 回答、ありがとうございました。
- osamuy
- ベストアンサー率42% (1231/2878)
拡張正規表現を使って、 my @data = ("AAAA,BB,CCC,EEEE,F" =~ /(?>\w{3,})/g); とか。
お礼
こんな書き方もあるんですね。 勉強になりました。 ありがとうございました!
お礼
こんな書き方もあるんですね。 ちょっと自分には高度過ぎるので、もう少し勉強してから見直します。 回答ありがとうございました。