まずはタグにヒットする正規表現。たとえばこんな感じ。
/<\/?[^>]+>/
で、タグの始まり < 以外の文字(列)にヒットする正規表現。
/[^<]+/
これらを OR でくっつけて、ヒットした文字(列)をキャプチャできるようにそれぞれ () で括っておきます。gオプションも付けておく。
var matchpattern = /(<\/?[^>]+>)|([^<]+)/g ;
で、
var html = '<span>こんにちは。</span>Hello, WORLD!<br />' ;
みたいなhtmlタグを含む文字列内のhtmlタグ以外の部分を、例えば「タグではありません」という文字列に置換してみる。
/* htmlタグ以外の部分を「タグではありません」という文章に置換 */
var matchpattern = /(<\/?[^>]+>)|([^<]+)/g ;
var html = '<span>こんにちは。</span>Hello, WORLD!' ;
var replaced = html.replace( matchpattern ,
function(){
if( arguments[1] ) return arguments[1] ;
if( arguments[2] ) return 'タグではありません' ;
} );
// 結果 : replaced = '<span>タグではありません</span>タグではありません<br />' ;
var matchpattern = /(<\/?[^>]+>)|([^<]+)/g ;
var html = '<span>こんにちは。</span>Hello, WORLD!' ;
var replaced = html.replace( matchpattern ,
function(){
if( arguments[1] ) return arguments[1] ;
if( arguments[2] ) return 'タグではありません' ;
} );
// 結果 : replaced = '<span>タグではありません</span>タグではありません<br />' ;
arguments[1]には、マッチパターンのひとつめの()グループに捕捉された文字列が入ります。つまり今回の場合は htmlタグが入る筈。タグは置換したくないので、ヒットした文字列をそのまま返してやる。
arguments[2]には、マッチパターンのふたつめの()内の正規表現に捕捉された文字列が入ります。正規表現内の OR ( | 記号)は左側から評価されるので、| の右側で捕捉されるのは「htmlタグにマッチしなかった、文字 < を含まない1文字以上の文字(列)」ですね。
これで、元のタグ/スタイルを維持しながら何かできる。
ただし、例えば操作したい文字列が「<span>こん<にちは。</span>Hello, WORLD!」のように、タグ以外の部分に<が入っていると上手くいかないのですが、普通は文章中の < は < と書く筈なので、スルーしておきます。
もうひとつ。
/* htmlタグ以外の半角英数記号部分に何かスタイルを付加 */
var matchpattern = /(<\/?[^>]+>)|([\s!-;=-~]+)/g ;
var html = '<span>こんにちは。</span>Hello, WORLD!<br />' ;
var replaced = html.replace( matchpattern ,
function(){
if( arguments[1] ) return arguments[1] ;
if( arguments[2] ) return '<span style="color:red;">' + arguments[2] + '</span>' ;
} );
// 結果 : replaced = '<span>タグではありません</span><span style="color:red;">Hello, WORLD!</span><br />' ;
var matchpattern = /(<\/?[^>]+>)|([\s!-;=-~]+)/g ;
var html = '<span>こんにちは。</span>Hello, WORLD!<br />' ;
var replaced = html.replace( matchpattern ,
function(){
if( arguments[1] ) return arguments[1] ;
if( arguments[2] ) return '<span style="color:red;">' + arguments[2] + '</span>' ;
} );
// 結果 : replaced = '<span>タグではありません</span><span style="color:red;">Hello, WORLD!</span><br />' ;
半角/全角/タグが入り組んだhtmlでも大丈夫。→サンプル。
置換ではなく、マッチさせたいだけなら exec を使って回してやります。
/* htmlをタグとそれ以外に仕分ける */
var tags ;
var others ;
var result ;
var matchpattern = /(<\/?[^>]+>)|([^<]+)/g ;
var html = '<span>こんにちは。</span>Hello, WORLD!<br />' ;
while( result = matchpatterm.exec( html ) ){
if( result[1] ){
tags[ tags.length ] = result[1] ;
}else if( result[2] ){
others[ others.length ] = result[2] ;
}
}
// 結果 : tags[0] = '<span>' ; tags[1] = '</span>' ; tags[2] = '<br />' ;
// 結果 : others[0] = 'こんにちは。' ; others[1] = 'Hello, WORLD!' ;
var tags ;
var others ;
var result ;
var matchpattern = /(<\/?[^>]+>)|([^<]+)/g ;
var html = '<span>こんにちは。</span>Hello, WORLD!<br />' ;
while( result = matchpatterm.exec( html ) ){
if( result[1] ){
tags[ tags.length ] = result[1] ;
}else if( result[2] ){
others[ others.length ] = result[2] ;
}
}
// 結果 : tags[0] = '<span>' ; tags[1] = '</span>' ; tags[2] = '<br />' ;
// 結果 : others[0] = 'こんにちは。' ; others[1] = 'Hello, WORLD!' ;
result[1] には、正規表現のいっこめの()でキャプチャされた文字(列) = つまりhtmlタグが、result[2]にはふたつめの()でキャプチャされた文字(列)が入ります。
単にhtmlタグ以外の部分をGetしたいなら、DOM操作でテキストノードを探索するほうが楽なような気がしないでもない。
コメント