• ベストアンサー

置き換えについて

$com =~ s/([-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)/$1<br>/g; 上記のように、 [-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+ が含まれる箇所を置き換えしているのですが、 s?https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+ が含まれる箇所は、置き換えを適用しないようにしたいのですが、 昨日から思考錯誤しておりますが、見当が付きませんでした。 それと、s?はどのような意味があるのでしょうか? 質問ばかりで申し訳ございませんが、宜しくお願いいたします。

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

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

ShiftJISにきちんと対応するには [^A-Za-z] のところをいじる必要があります。 #!/usr/bin/perl use strict; use warnings; use Fatal qw(:void open close); use feature ':5.10'; my $chars = qr{[-_.!~*\'()a-zA-Z0-9;/?:\@&=+\$,%#]}; my $com = 'aaaaaあいうえおhttp://okwave.jp/かきくけこbbbbbbb'; $com =~ s{ ( http://$chars+ | [^A-Za-z]+ | ($chars (?! http:// )){1,3}) }{$1<br>\n}gx; say $com; 多分効率も最悪w >perl okw0311.pl aaa<br> aa<br> あいうえお<br> http://okwave.jp/<br> かきくけこ<br> bbb<br> bbb<br> b<br>

MKNET
質問者

お礼

有難うございます。 教えていただいた方法を試してみましたところ、エラーが生じてしまいました。 | [^A-Za-z]+ この部分を削除してみましたところ希望通りの動作で動いてくれましたが、削除しても問題ないでしょうか。初歩的な質問で申し訳ありませんが、宜しくお願いいたします。

その他の回答 (4)

  • Gotthold
  • ベストアンサー率47% (396/832)
回答No.5

最初のs?はshttpを考慮してるんだと思う。 shttpのサイトなんて見たことないけどね。 httpsの方がはやったから廃れたっぽい。 > 教えていただいた方法を試してみましたところ、エラーが生じてしまいました。 こっちで試してみたけど動いたよ。 環境とエラー内容くらい提示してみたら? リンクになってる文字列の前後に、 ZERO WIDTH SPACE がついてたからこのせいかもね。 単純にコピーするとこんなになっちゃう。 $com =~ s{ ( ​http://$chars+​ | [^A-Za-z]+ > この部分を削除してみましたところ希望通りの動作で動いてくれましたが 削除するとこんな風になるんだけど、希望通り? aaa<br> aa<br> あいうえおhttp://okwave.jp/<br> かきくけこbbb<br> bbb<br> b<br>

MKNET
質問者

お礼

有難うございます。 申し訳ございません。エラーは勘違いでございました。 Perlのバージョンは5.8.8です。 コメント中に<br>の改行が含まれていた場合に表示おかしくなってしまいました。 my $com = 'aaaaaあいうえお?http://okwave.jp/?かきくけこ<br>bbbbbbb'; の場合ですと、 aaa<br> aa<br> あいうえお<br> http://okwave.jp/<br> かきくけこ<br> < br > bbb<br> bbb<br> b<br> このように表示されてしまいました。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

できるかどうか知らないけど, 「split で分解して置換を行い, join でつなげる」という後ろ向きな解決策はあるかも. my @words = split(m{(s?https?:(略)+)}, $com); for my $word (@words) { $word =~ s/..../g unless $words =~ m{^s?https?:....}; } $com = join('', @words); とか. でも, 最初の s? って何の意味があるんだろう. これ自体は「s が 1個あってもいいしなくてもいい」なんだけど, その後に http (あるいは https) というプロトコルが続くのは意味不明だなぁ.

MKNET
質問者

お礼

有難うございます。 最初のs?はhttp://okwave.jp/qa4756049.htmlこちらで教えていただいたものを使わせてもらっていたのですが、無くても構わないようですので、今後は外してみようと思います。 教えていただいた方法を試してみましたところ、 $word =~ s/..../g unless $words =~ m{^s?https?:....}; この部分でエラーが生じているようでした。いろいろ弄ってみようと思います。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

何をどう置き換えようとしているのか (あるいは置き換えないようにしようとしているのか) が全くわからないんだけど, Perl... だよねぇ. 単に「これこれにマッチしなかったら置き換える」じゃダメ?

MKNET
質問者

お礼

有難うございます。伝わり難い説明で申し訳ありません。 半角文字の先頭がhttpの場合は置き換えを適用しないというように考えています。 my $com = 'aaaaaあいうえおhttp://okwave.jp/かきくけこbbbbbbb' $com =~ s/([-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]{3})/$1<br>/g; print $com\n; 例えば上記設定でしたら以下のように表示させたいと考えていますが、 http://okwave.jp/が改行されないようにするにはどのような条件で書けばいいのかわかりません。 aaa aa あいうえお http://okwave.jp/ かきくけこ bbb bbb b

MKNET
質問者

補足

補足です。 &auto_link($com); sub auto_link { $_[0] =~ s/([^=^\"]|^)(s?https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)/$1<a href=\"$2\">$2<\/a>/g; } auto_linkのリンクに改行が入ってしまうことを防ぎたいために、上記方法を試行錯誤しております。

  • ORUKA1951
  • ベストアンサー率45% (5062/11036)
回答No.1

 まず、[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+だと、ほとんどすべての半角英数字記号文字列にマッチしてしまいますよ。 最長マッチ ? は0個か1個 *は0個以上 +は一個以上 {2}は2個 {2,}は2個以上 {,4}は4個以下 最短マッチ ?? は0個か1個 *?は0個以上 +?は一個以上 {2}?は2個 {2,}?は2個以上 {,4}?は4個以下  

MKNET
質問者

お礼

アドバイス有難うございます。細かく意味を教えていただき大変勉強になりました。 上記条件での置き換えは普通のやり方では困難な事なのでしょうか?簡単な改造知識しか知らないため途方に暮れております。