JavaScriptで「htmlタグ以外」にヒットさせる正規表現。

…そんなものは無さそうなので、exec や replace のキャプチャ機能を使ってこんなふうにするとよいみたい。

まずはタグにヒットする正規表現。たとえばこんな感じ。

/<\/?[^>]+>/

で、タグの始まり < 以外の文字(列)にヒットする正規表現。

/[^<]+/

これらを 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 />' ;

arguments[1]には、マッチパターンのひとつめの()グループに捕捉された文字列が入ります。つまり今回の場合は htmlタグが入る筈。タグは置換したくないので、ヒットした文字列をそのまま返してやる。

arguments[2]には、マッチパターンのふたつめの()内の正規表現に捕捉された文字列が入ります。正規表現内の OR ( | 記号)は左側から評価されるので、| の右側で捕捉されるのは「htmlタグにマッチしなかった、文字 < を含まない1文字以上の文字(列)」ですね。

これで、元のタグ/スタイルを維持しながら何かできる。

ただし、例えば操作したい文字列が「<span>こん<にちは。</span>Hello, WORLD!」のように、タグ以外の部分に<が入っていると上手くいかないのですが、普通は文章中の < は &lt; と書く筈なので、スルーしておきます。

もうひとつ。

/* 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 />' ;

半角/全角/タグが入り組んだ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!' ;

result[1] には、正規表現のいっこめの()でキャプチャされた文字(列) = つまりhtmlタグが、result[2]にはふたつめの()でキャプチャされた文字(列)が入ります。

単にhtmlタグ以外の部分をGetしたいなら、DOM操作でテキストノードを探索するほうが楽なような気がしないでもない。

カテゴリ: