2008-09-17 9 views
1

ユーザー入力のタグを実際のhtmlタグに置き換えるJavaScript RegExを作成しようとしています。したがって[b]<b>になります。JavaScriptのRegExサブ処理を処理する

[b]hello[/b] [u]world[/u] 

が、タグがネストされている場合:正規表現私は、これは例えば、単一のネストされたタグ、ため正常に動作しますので、

var exptags = /\[(b|u|i|s|center|code){1}]((.){1,}?)\[\/(\1){1}]/ig; 

次のJavaScript

s.replace(exptags,"<$1>$2</$1>"); 

とのようなルックスを使用しています互いに内側には、外側のタグにのみ一致します。たとえば、

[b]foo [u]to the[/u] bar[/b] 

これはbタグにのみ一致します。どうすればこの問題を解決できますか?開始文字列が結果と同じになるまでループする必要がありますか?私は((.){1,}?) pattenも間違っているという気持ちがありますか?

ありがとう

+0

私は、誰もここにこれを残さなかった信じることができません。http://stackoverflow.com/a/1732454/20074 – Ken

答えて

1

AFAIKでは、正規表現で再帰を表現することはできません。

ただし、.NETのSystem.Text.RegularExpressionsでバランスマッチングを使用して行うことができます。ここをクリックしてください:http://blogs.msdn.com/bclteam/archive/2005/03/15/396452.aspx

.NETを使用している場合は、おそらくコールバックで必要なものを実装できます。 そうでなければ、あなた自身の小さなjavascriptパーサーを動かさなければならないかもしれません。

もう一度、サーバーにヒットする余裕があれば、完全なパーサーを使用できます。 :)

とにかくこれは何が必要ですか?プレビュー以外のものであれば、サーバ側で処理することを強くお勧めします。

+0

はいそのコメントをエリアのライブプレビュー、そのPHP側のサーバのために、しかし、持っていますそのビットのコード。 – Re0sless

0

はい、ループする必要があります。代わりに、あなたのタグはHTMLのように見えるので、の代わりに[b]を、</b>の代わりに[/b]を置き換えることができます。 (。){1、}?は、(。*?)と同じです。つまり、シンボル、可能な限り最小のシーケンス長です。

更新日:MrPさん、(。){1、}さんに感謝しますか? +。私の悪いです。

0

あなたは内側のパターンが厄介なことについては正しいですか?

((.){1,}?) 

これは少なくとも1回はキャプチャした試合を行い、その後すべてがキャプチャされます。あなたのタグの中のすべての文字はグループとして捕捉されます。

あなたがそれを必要としないときに閉じる要素名をキャプチャしていて、そのことが暗示されている場合は{1}を使用しています。以下はクリーンアップ版です:

/\[(b|u|i|s|center|code)](.+?)\[\/\1]/ig 

他の問題についてはわかりません。

0

正規表現がもはや一致しなくなるまで、正規表現を繰り返し適用することができます。それは "[b] [b] foo [/ b] [/ b]" => "< b> [f] </b> [/ b]" => "< b> < b > foo </b> </b> "しかし、私が見る限りでは、最終的な結果は一致する(必ずしも適切に入れ子になっていない)タグであっても賢明な文字列になります。

「正しく」実行したい場合は、単純な再帰的降下パーサーを作成します。人々は "[b] foo [u] bar [/ b] baz [/ u]"が動作することを期待しているかもしれませんが、パーサで認識するのは難しいです。

0

入れ子ブロックが置き換えられないのは、[b]の一致が[/ b]の後ろに配置されるためです。したがって、((。){1、}?)が一致するものはすべて無視されます。

サーバサイドで再帰的なパーサを書くことができます - Perlはqr//を使い、Rubyはおそらく類似しています。

ただし、必ずしも真の再帰が必要なわけではありません。あなたは、等価文字列を処理するために、比較的単純なループを使用することができます。

0: [b]hello[/b] [u]world[/u] [b]foo [u]to the[/u] bar[/b] 
1: <b>hello</b> <u>world</u> <b>foo [u]to the[/u] bar</b> 
2: <b>hello</b> <u>world</u> <b>foo <u>to the</u> bar</b> 

また、クリーンアップのためのいくつかの提案:

var s = '[b]hello[/b] [u]world[/u] [b]foo [u]to the[/u] bar[/b]'; 
var exptags = /\[(b|u|i|s|center|code){1}]((.){1,}?)\[\/(\1){1}]/ig; 

while (s.match(exptags)) { 
    s = s.replace(exptags, "<$1>$2</$1>"); 
} 

document.writeln('<div>' + s + '</div>'); // after 

この場合は、2回のパスを作ってあげます正規表現:なし

var exptags = /\[(b|u|i|s|center|code)\](.+?)\[\/(\1)\]/ig; 
  • は{1}が想定されますカウント指定子は
  • {1、}リチャードSZALAYに同意+
+0

[center] [/ center]をテストケースに追加し、あるタグを別のタグの中に入れて下から正規表現を取り上げると、私はあなたの答えを投票します。 –

+0

「別のタグの中に1つのタグを入れ子にする」という意味では、「自分自身の中に同じタグがある」という意味です。たとえば、[b] foo [b] bar [/ b] baz [/ b] –

0

に短縮することができます存在しますが、彼の正規表現は、右引用されていませんでした:

var exptags = /\[(b|u|i|s|center|code)](.*)\[\/\1]/ig; 

がきれいです。 .+?.*に変更しています。 .+?には二つの問題があります。

  1. あなたは[/ U] [U]を一致しません、それらの間に少なくとも1つの文字(+)
  2. がないので、非欲張りマッチは」勝ちました自分自身の中にネストされた同じタグを持つようにうまくトンの契約
0

どの程度(?):私にとって

tagreg=/\[(.?)?(b|u|i|s|center|code)\]/gi; 
"[b][i]helloworld[/i][/b]".replace(tagreg, "<$1$2>"); 
"[b]helloworld[/b]".replace(tagreg, "<$1$2>"); 

上記の生成:

<b><i>helloworld</i></b> 
<b>helloworld</b> 

これはあなたが望むように見え、1回のパスしか必要としないという利点があります。

免責事項:私は、最も簡単な解決策は、彼らがしているかどうか、すべてのタグを交換することであろう:-)

3

私は間違いをしたので、もしそれらを指摘すること自由に感じなさい、JSで頻繁にコーディングしません閉鎖されていないかどうかを確認し、一致するかどうかを確認してください。.innerHTMLがうまくいきます。

var tagreg = /\[(\/?)(b|u|i|s|center|code)]/ig 
div.innerHTML="[b][i]helloworld[/b]".replace(tagreg, "<$1$2>") //no closing i 
//div.inerHTML=="<b><i>helloworld</i></b>"