ショボ短歌会

$com =~ s/([-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)/$1<br>/g;

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

質問ばかりで申し訳ございませんが、宜しくお願いいたします。

A 回答 (5件)

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>
    • good
    • 0
この回答へのお礼

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

お礼日時:2009/03/12 19:15

最初の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>
    • good
    • 0
この回答へのお礼

有難うございます。
申し訳ございません。エラーは勘違いでございました。
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>

このように表示されてしまいました。

お礼日時:2009/03/12 21:52

できるかどうか知らないけど, 「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) というプロトコルが続くのは意味不明だなぁ.
    • good
    • 0
この回答へのお礼

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

お礼日時:2009/03/12 19:11

何をどう置き換えようとしているのか (あるいは置き換えないようにしようとしているのか) が全くわからないんだけど, Perl... だよねぇ.


単に「これこれにマッチしなかったら置き換える」じゃダメ?

この回答への補足

補足です。
&auto_link($com);
sub auto_link {
$_[0] =~ s/([^=^\"]|^)(s?https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)/$1<a href=\"$2\">$2<\/a>/g;
}

auto_linkのリンクに改行が入ってしまうことを防ぎたいために、上記方法を試行錯誤しております。

補足日時:2009/03/11 00:19
    • good
    • 0
この回答へのお礼

有難うございます。伝わり難い説明で申し訳ありません。
半角文字の先頭が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

お礼日時:2009/03/11 00:10

 まず、[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+だと、ほとんどすべての半角英数字記号文字列にマッチしてしまいますよ。



最長マッチ
? は0個か1個
*は0個以上
+は一個以上
{2}は2個
{2,}は2個以上
{,4}は4個以下
最短マッチ
?? は0個か1個
*?は0個以上
+?は一個以上
{2}?は2個
{2,}?は2個以上
{,4}?は4個以下
 
    • good
    • 0
この回答へのお礼

アドバイス有難うございます。細かく意味を教えていただき大変勉強になりました。


上記条件での置き換えは普通のやり方では困難な事なのでしょうか?簡単な改造知識しか知らないため途方に暮れております。

お礼日時:2009/03/10 21:18

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!