プロが教えるわが家の防犯対策術!

JavaScriptで連続する空白を、htmlタグ付きで別の文字の連続に置換する方法

※可視化のため下記のサンプルでは、空白を「_」で表現しています
「_」の連続を、「#」の連続とそれをタグで囲んだ状態にしたいと思っています。

やりたいことはこんな感じです。
(0):置換前:hoge_hogehove___asd#bn__
(1):置換後:hoge<span class="…">#</span>hogehove<span class="…">###</span>asd#bn<span class="…">##</span>


しかし正規表現の書き方が分からなかった為、現状のコードはこんな感じにしています。
str.replace(/_/g, "<span class='…'>#</span>");

実行結果はこうなります。
(2):現状:hoge<span class="…">#</span>hogehove<span class="…">#</span><span class="…">#</span><span class="…">#</span>asd#bn<span class="…">#</span><span class="…">#</span>

無駄に長いのですがとりあえず現状でも、htmlとして表示したときの結果は間違っていません。
しかし
・正規表現を十分に理解できていないレベルの低いコードっぽい
・最終的には比較的多くの文字列を処理をする
・保持しておいて繰り返し表示するので置換後の文字列を小さくしておきたい
と思っています。


(0)を(1)の状態に変換する方法を教えてください。
出来れば正規表現でシンプルにパシッと決める方法を希望しています。
よろしくお願いします。

A 回答 (9件)

// JavaScript 1.3, Jscript 5.5, ECMA 262-3


'hoge_hogehove___asd#bn__'.replace(/_+/g, function(s) { return '\x3Cspan class="hoge">' + s.replace(/_/g, '#') + '\x3C/span>'; });

この回答への補足

「\x3C」とありましたが、「\x3C」でも「<」でも大丈夫でした。
環境を書き忘れていましたが、WinXP IE8 HTAとして実行です。
環境によって「\x3C」でなければならない場合もあるのですかね?

とりあえず、私の環境では大丈夫でしたが、汎用的な環境を想定し
ご回答をいただいたのかと思います。

本当に参考になりました。ありがとうございました。

補足日時:2010/11/08 18:04
    • good
    • 0
この回答へのお礼

試したところ期待通りに動きました。
すごいです。こんな書き方が出来るのですね。
私が心の奥で求めていた方法と一致します。

今回は本当に質問してよかったです。
比較的短時間に、複数の方にいろいろな方法を
教えていただけ大変勉強になりました。

ありがとうございました。

お礼日時:2010/11/08 17:41

No3です。



>1回目の置換でつけたspanタグ内の空白も置換してしまった為、
>希望の動きにはなりませんでした。
ありゃ、うっかりしてました。 そうですね。

すでに、No4様が回答なさってますが、それを応用させて頂いて…
(できそうな気がしてたんだけど、引数で受ける方法が分からなかった<お勉強させて頂きました)

var str = "hoge_hogehove___asd#bn__";
str=str.replace(/(_+)/g, function(s){return '<span class="…">'+s.replace(/_/g,'#')+'</span>';});
alert(str);

で、いけるみたい。(IE6でもOKでした)
    • good
    • 0
この回答へのお礼

ANo.6さんの内容と同じですね。
回答タイミングの差かもしれませんが。

今回はいろいろ勉強になりました。
ありがとうございました。

お礼日時:2010/11/08 18:18

連続済みません。


No.7は#が1つしかないので、No.6のようにしないとダメですね。


別の方法で。

str=str.replace(/(_+)/g, function(s){return '<span class="">'+Seq(s,s.length)+'</span>';});

var Seq=function(s, n){var r='';while(n){r+=s;n--};return r;};


var Seqをreplace中の無名関数に入れても動くはずですが、遅くなります。
    • good
    • 0
この回答へのお礼

試してみましたが、そのままではダメでした。

しかし新たな提案を試みていただき
ありがとうございました。

お礼日時:2010/11/08 18:13

#に変換を忘れていました。



str=str.replace(/(_+)/g, function(s){return '<span class="">#</span>';});
    • good
    • 0
この回答へのお礼

試してみましたが、そのままではダメでした。

しかし新たな提案を試みていただき
ありがとうございました。

お礼日時:2010/11/08 18:13

一旦スペースをキーボード入力できない文字に変換するのはどうでしょう。




var str = "hoge hogehove asd#bn ";

//スペースを「\0」に置換
str = str.replace(/ /g, "\0");
//後方参照にて「\0+」にspanタグのプレフィックスとサフィックスを追加
str = str.replace(/(\0+)/g, "<span class='…'>$1</span>");
//「\0」を「#」に変換
str = str.replace(/\0/g, "#");

alert(str);


一行で書いても構いません。
    • good
    • 0
この回答へのお礼

私の最初のコードで得られる結果よりはるかにいい方法ですね。
ただ、3回の置換は少し冗長に感じます。

ただ、「\0」でいったん退避するという方法はユニークであり
参考になりました。ありがとうございました。

お礼日時:2010/11/08 17:55

str=str.replace(/(_+)/g, function(s){return '<span class="">'+s+'</span>';});



これでどうでしょうか。

_ を半角スペースに変換して下さい。(1カ所)


Ajax未対応ブラウザ、IE5.5、IE6で動かないかもしれません。
    • good
    • 0
この回答へのお礼

第二引数に関数を指定できるんですね。
知りませんでした。

この方法を知ったことで、私の対応能力がだいぶ高まったと思います。
大変勉強になりました。ありがとうございました。

お礼日時:2010/11/08 17:50

もっとうまい方法があるかも知れませんが…



var str = "hoge_hogehove___asd#bn__";
str = str.replace(/(_+)/g, "<span class='…'>$1</span>").replace(/_/g, "#");

alert(str);

この回答への補足

いけたと思ったのですが、「_」はあくまでも空白であるため1回目の置換でつけたspanタグ内の空白も置換してしまった為、希望の動きにはなりませんでした。

仕方がないので最後に「.replace(/span#class/g, "span class");」を入れ、3発置換にしました。

しかしこれだと最初の文字列の段階で「span#class」という文字列があった場合には意図せぬ置換を行なうことになってしまいます。が、実際にはまずないであろうと思われる文字列なので、とりあえずはいいことにしました。


質問前は「無理かも」と思っていたのですが意外といろいろな案が出てくるので、もしかしたらさらなる良案が出てくるかもしれないので、もう少し様子を見させていただきます。

補足日時:2010/11/08 13:32
    • good
    • 0
この回答へのお礼

うわ。これですね。
普通に2段階で置換すればいいだけだったんですね…。
意味合い的にも最も適しているように感じます。

難しく考えすぎていたのかもしれません。
大変参考になりました。ありがとうございました。


※てか、皆さんのご回答が早くてびっくりしています。
今回は本当に、質問してよかったです。

お礼日時:2010/11/08 13:15

追記。


 
冗長部分を取り去る際に無関係な他のタグまで置換しちゃうと困るので、以下のようにしましょう。
 
1.一旦、未定義タグを追加する
str.replace(/_/g, "<xxst>#<xxed>");
 
hoge_hogehove___asd#bn__

hoge<xxst>#<xxed>hogehove<xxst>#<xxed><xxst>#<xxed><xxst>#<xxed>asd#bn<xxst>#<xxed><xxst>#<xxed>
 
2.冗長部分を削除する
str.replace(/<xxed><xxst>#/g, "#");
 
hoge<xxst>#<xxed>hogehove<xxst>#<xxed><xxst>#<xxed><xxst>#<xxed>asd#bn<xxst>#<xxed><xxst>#<xxed>

hoge<xxst>#<xxed>hogehove<xxst>###<xxed>asd#bn<xxst>##<xxed>
 
3.未定義タグを本来のタグに置き換える
str.replace(/<xxst>/g, "<span class='…'>");
str.replace(/<xxst>/g, "</span>");
 
hoge<xxst>#<xxed>hogehove<xxst>###<xxed>asd#bn<xxst>##<xxed>

hoge<span class="…">#</span>hogehove<span class="…">###</span>asd#bn<span class="…">##</span>
 
正規表現の指定時に「/」記号を使用するので「途中結果では『/』を含まない文字列を使って、最後の最後で『/』を含む文字列に置換している」と言う事に注意すること(そうしないと正規表現の置換元の文字列の指定がメンド臭い事になる)
    • good
    • 0
この回答へのお礼

追加で別の方法も考えていただきありがとうございました。
今回はいろいろ勉強になりました。

お礼日時:2010/11/08 17:46

>(2):現状:hoge<span class="…">#</span>hogehove<span class="…">#</span><span class="…">#</span><span class="…">#</span>asd#bn<span class="…">#</span><span class="…">#</span>


 
文字列「hoge<span class="…">#</span>hogehove<span class="…">#</span><span class="…">#</span><span class="…">#</span>asd#bn<span class="…">#</span><span class="…">#</span>」の「</span><span class="…">#」を正規表現の置換を使って「#」に置換したらどうなりますか?
 
冗長になるのが判っているなら、冗長にしたあとで、冗長部分を削除すれば良いでしょう。
 
そりゃ「一発で冗長部分を作らずに最適な置換をする」と気持ち良いですが「結果が最適化されてりゃ、途中はどうでもいい」と思いませんか?
    • good
    • 0
この回答へのお礼

おお。逆転の発想といいますか、私には無かった発想です。
正規表現での置換を1行追加しただけで実現できました。

「一発」ではありませんが、私が質問で掲げた「シンプルにパシッ」
には十分該当する解決策だと思います。


私が抱えている課題は一旦解決しました。
しかしそれ以上に、行き詰まったときには
少し違った角度からアプローチしたり、考え方を変えてみたりすると
出口が見える(場合もある)という好例を学ばせていただきました。

大変参考になりました。ありがとうございました。

お礼日時:2010/11/08 13:08

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