人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

javascriptの正規表現で、特定のパターンの時に文字を追加する方法を教えて下さい。

やりたい事
<font>123<font>456</font>789</font> のデータを
<font><span>123</span><font><span>456</span></font><span>789</span></font>
に置き換えたい。

置き換えは2ステップで実施したい。
1step目
<font>123<font>456</font>789</font> を配列に置き換える。
a[0]=<font>
a[1]=123
a[2]=<font>
a[3]=456
a[4]=</font>
a[5]=789
a[6]=</font>
の様にsplitしたい。
2step目は・・・forで処理できるので私でも作れると思います。

どうかよろしくお願いします。


●質問者: kameoyaji_2
●カテゴリ:ウェブ制作
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● Cherenkov
●100ポイント
var src = '<font>123<font>456</font>789</font>';
var new_src = src.replace(/(\d+)/gi, '<span>$1</span>');
console.log(new_src)
console.log(new_src == '<font><span>123</span><font><span>456</span></font><span>789</span></font>'); //true

これでできます。配列にするパターンも必要ですか?


kameoyaji_2さんのコメント
出来れば、配列にするパターンでお願いします。 追加する時に、TAG(<font>)をパースして、fontの属性を元にspanの属性を設定してあげないといけないもので。

Cherenkovさんのコメント
それだと入れ子になったfontの場所の特定がごちゃごちゃになりませんかね。 特定パターンなら「fontの属性を元にspanの属性を設定」の例を提示して正規表現でやっちゃったほうがいいのでは

Cherenkovさんのコメント
うーん… >|javascript| var src = '<font id="a">123<font id="b">456</font>789</font>'; var ary = src.split(/(<.+?>)/); ary.shift() ary.pop() console.log(ary) ||<

kameoyaji_2さんのコメント
これだと、 a[0]=123 a[1]=456 a[2]=789 になってしまいますね。 a[0]=&#60;font&#62; a[1]=123 a[2]=&#60;font&#62; a[3]=456 a[4]=&#60;/font&#62; a[5]=789 a[6]=&#60;/font&#62; にはできないものでしょうか? 実際には、元の色情報を元に、文字色と背景色を特定のパラメータ(可変の計算式)で変換したいもので、単純置き換えが出来ないのがつらいところです。

Cherenkovさんのコメント
そうなりますよ

Cherenkovさんのコメント
>|javascript| var src = '<font id="a">123<font id="b">456</font>789</font>'; var ary = src.split(/(<.+?>)/); ary.shift() ary.pop() alert(ary) alert(ary[0]) alert(ary[1]) ||<

Cherenkovさんのコメント
「元の色情報を元に、文字色と背景色を特定のパラメータ(可変の計算式)で変換したい」 そのサンプルを提示してみてはいかがでしょうか。特定パターンならfor文とか必要ないかもしれませんよ。 replace一発で計算結果に置換できるかも。

kameoyaji_2さんのコメント
現状は、下記の様なソースで、実現させています。 java初心者+正規表現未熟者 なもので、 ソースの視認性は悪いは、処理のコストが高いわで、 正規表現の処理に切り替えて、視認性と、処理コストを低めたいと考えています。 var src = '&#60;font id="a"&#62;123&#60;font id="b"&#62;456&#60;/font&#62;789&#60;/font&#62;'; var ary = new Array(); var s_flg = false; var s_str = ""; var FirstFlg = true; for ( var i = 0 ; i < src.length ; i ++ ){ var wchar = src.charAt(i); if ( wchar == "&#60;" ){ if ( !FirstFlg ){ ary.push(s_str); s_str = ""; } s_flg = true; } if ( wchar == "&#62;" ){ if ( s_flg ){ s_str += wchar; ary.push(s_str); s_str = ""; continue; } } FirstFlg = false; s_str += wchar; } for ( var i = 0 ; i < ary.length ; i ++){ var a_str = ary[i]; if ( a_str.length == 0 ){ continue; } var wstr = a_str.charAt(0); if ( wstr == '&#60;' ){ /* ノードと判断出来る */ } else { /*テキスト又はデータと判断出来る */ ary[i] = "&#60;span&#62;" + a_str + "&#60;/span&#62;"; } } /* innnerHTMLを再構成する */ var v_div = document.createElement('div'); v_div.innerHTML = ary.join(''); /* ノードを再帰的に追いかけて属性を書き換える処理 */ func1(v_div);

a-kuma3さんのコメント
文字列で処理しようとするから、ぐちゃぐちゃしちゃうんじゃないでしょうか。 質問にある「特定のパターン」というのが、タグじゃない、ということであれば、DOM を使う方がすっきりすると思います。

Cherenkovさんのコメント
文字列で処理するならば、「想定する特定パターンの入力の文字列」と「希望する出力の文字列」を提示してみるのはどうでしょう。 a-kuma3がおっしゃるようにDOMを掴んで処理したほうが正規表現でやるよりいいと思います。 DOMで処理するならば「想定する入力のHTML」と「希望する出力のHTML」を提示してみてください。 (そもそも入れ子のfontというのは修正したほうがいいと思いますが)

kameoyaji_2さんのコメント
入れこのフォントは・・・・。 他のシステムから、HTMLは作られてきている物で、入れこのFONTを止めて・・とは言えないです。 文字列の加工を行った後は、DOMのいinnerHTMLにHTMLの文字列を渡して、nodeを再帰的に辿って処理をする予定でいます。 fontの入れ子(タグの入れ子でもありますが)が無ければ、何もしなくてもよいのですが、fontが入れ子になっているために、一番最初に記載させていただように、 実際に表示すべき textの部分を、<span>タグでくくってからdomでパースさせたいと考えています。 そうしないと、nodeツリーをたどって、子ノードが無い(#text等は有ってもタグが存在しない)ノードで#textを入手し連結して表示されるテキスト文字を構成することが出来ないもので。 最終的に行いたいのは、入れ子のFONTタグをなくして、入れ子なしでSPANで作成する+同時に色を調整する。 というのが最終的な作りたい動きです。

Cherenkovさんのコメント
「最終的に行いたいのは、入れ子のFONTタグをなくして、入れ子なしでSPANで作成する+同時に色を調整する」 そのサンプルを提示したほうが、話が早いと思うのですが。

2 ● a-kuma3
●100ポイント ベストアンサー

入れ子の構造になった状態の HTML から、特定の属性を拾って、平らな構造の SPAN でくくった表現に変換するコードを書いてみました。

function extract_content(e, a) {
 var ee = e.firstChild
 do {
 if (ee.nodeType == 3) {
 var s = window.getComputedStyle(ee.parentNode)
 a.push({text: ee.textContent, font: s.fontSize, color: s.color})
 }
 if (ee.nodeType == 1) {
 extract_content(ee, a)
 }
 } while (ee = ee.nextSibling)
}
function change_flat_expression() {
 var source = document.getElementById("source")
 var list = []
 extract_content(source, list)
 var target = document.getElementById("result")
 for (var i = 0 ; i < list.length ; ++i) {
 var ee = document.createElement("SPAN")
 ee.style.color = list[i].color;
 ee.style.fontSize = list[i].font;
 ee.innerHTML = list[i].text
 target.appendChild(ee)
 }
 var s = target.innerHTML
 target = document.getElementById("result2")
 target.textContent = s
}

関数 change_flat_expression は、id="source" の要素配下の HTML から font-size と color の属性を拾って、入れ子の構造がない SPAN でくくった表現に変換します。

jsFiddle で試してみたのがこれです。
http://jsfiddle.net/ATYFq/

<font style="color: red;">
あああ
 <font class="C2">
 いいい
 <font style="font-size: large; color: green;">
 ううう
 </font>
 <font style="font-size: medium;">
 えええ
 </font>
 おおお
 </font>
</font>

という表記を、以下のように変換します(SPAN 単位の改行は手で入れてます)。

<span style="color: rgb(0, 0, 0); font-size: 12px;"> </span>
<span style="color: rgb(255, 0, 0); font-size: 12px;"> あああ </span>
<span style="color: rgb(0, 0, 255); font-size: 10px;"> いいい </span>
<span style="color: rgb(0, 128, 0); font-size: 14px;"> ううう </span>
<span style="color: rgb(0, 0, 255); font-size: 10px;"> </span>
<span style="color: rgb(0, 0, 255); font-size: 12px;"> えええ </span>
<span style="color: rgb(0, 0, 255); font-size: 10px;"> おおお </span>
<span style="color: rgb(255, 0, 0); font-size: 12px;"> </span>
<span style="color: rgb(0, 0, 0); font-size: 12px;"> </span>

見た目が同じになるのは、jsFiddle のコード を動かしてみれば分かると思います。
やりたいのは、こういうことではないでしょうか?


kameoyaji_2さんのコメント
やりたいことドンピシャです。 ありがとうございます。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ