館林です。
Shin-ichiro Hara <sinara / blade.nagaokaut.ac.jp> さんが
2000/02/08 午後 12:31:29に書いた
「[ruby-list:20580] Re: エスケープされていないものだけを置換」 のお返事です:
> 原です。
>
> |ごとけんです
>
> |適用範囲によりますが、これだと先頭の _ は置換できないので、
> |次のようにした方が安全かも知れません。
> |
> |a.gsub(/(^|[^\\])_/, '\1 ')
>
> これが正解と思いますが、もしかして \ で \ をエスケープ可能に
> してたりしません? a = "\\\\_" の場合とか。だとすると実直に
>
> a.gsub(/\\?[\\_]/) { case $& when "_" then " " else $& end }
>
> とかしたほうがいいかもしれません。
ありがとうございます。\\\\は考えていませんでした。たしかに
ありえます。
使わせていただいたところ、"_abc\\\\_d\\_e"もちゃんと、
" abc\\\\ d\\_e"と置換されました。
すごいです。質問してから、24時間たらずでいくつもの新しい発見
がありました。
僕の質問に答えていただいた皆さん、ありがとうございます。
以下、FAQっぽい物をつけてみます。
教えていただいた内容を適宜編集させていただいています。
Q.エスケープされていない文字だけを置換したいのです。
具体的には、_を空白に置換したいのですが、\_は置換したくないのです。
どうしたら良いのでしょうか?
A.
a = "_ab_c\\_d"
a.gsub(/[^\\][_]/," ")
だと、
"_a c\\_d"
とbまで消えてしまいますし、行頭の_も置換されません。
gsubは、以降のブロックで、$1という後方参照が利用できます。
a.gsub(/([^\\])[_]/){$1+" "}
"_ab c\\_d"
これを実行すれば、bは消えなくなりました。
でも、これよりも、
gsub(/([^\\])_/, '\1 ')
こっちのほうが、すっきりしているでしょう。
但し、行頭の '_' はまだ置換されません。
a.gsub(/(^|[^\\])_/, '\1 ')
" ab c\\_d"
と、これで、無事、行頭の'_'も置換できました。
しかし、 \ で \ をエスケープ可能にしてある場合は、
a = "\\\\_" # この場合、\\は_にかからない。
a.gsub(/\\?[\\_]/) { case $& when "_" then " " else $& end }
p a
"\\\\ "
とかしたほうがいいかもしれません。
ちなみに、Perlだと、
$a = "_abc_d\\_e_";
$a =~ s/(^|[^\\])_/\1 /g;
$a =~ s/(?<!\\)_/\1 /g; #5.005以降
$a =~ s/(\G|[^\\])_/\1 /g; #5.005以降
なんて書けます。
■参考URL
Mastering Regular Expressions
http://public.yahoo.com/~jfriedl/regex/
詳説正規表現
http://www.oreilly.co.jp/BOOK/regex.htm
「詳説正規表現」読書メモ (by なひ)
http://www.jin.gr.jp/~nahi/src/mre.html
正規表現メーリングリスト
http://www.bug.org/ML/regexp/
正規表現メモ
http://www.kt.rim.or.jp/%7ekbk/regex/regex.html
========================================================
綾乃介@IBARAKI Univ.
E-mail: aya / big.or.jp
URL:http://www5.big.or.jp/~aya/
========================================================
茨城県日立市の総合情報サイト
メディアネットワーク マンボウ WebSite
http://manbow.cgi-space.to/
========================================================