タグにマッチさせる正規表現

HTMLタグ文字列にマッチさせる正規表現を書いてみた。

//html
var rtag = /<\w+(?:\s+\w+(?:\s*=\s*(?:".*?"|'.*?'|[^'">\s]+))?)?(?:\s?\/)?>|<\/\w+>/g;

//(x)html
var rxtag = /<\w+(?::\w+)?(?:\s+\w+(?:\s*=\s*(?:".*?"|'.*?'|[^'">\s]+))?)?(?:\s?\/)?>|<\/\w+(?::\w+)?>/g;

何かこんなに書かなくても良いように思う。(-_-;)

とりあえず、簡単にテスト。
var tagStr = [
    "<br/>",
    "<br />",
    "<p>abc<br>abc<br>abc</p>",
    "<h1></h1>",
    '<div style="vertical-align:bottom;"><span>foo</span></div>',
    "<img src='http://www.example.com' alt='&'/>",
    "<script type='text/javascript'><" + "/script>",
    "<p>123ABCあいうえお</p>",
    "abc<span>def\t\u3000\nghi</span>jklm",
    "<input type='text' value='A > B' />",
    "<style type='text/css'>\nbody{\n\tfont-family:'メイリオ',Meiryo;\n}\n</style>",
    "<gd:name value='foo'/>"
];

for ( var i = 0; i < tagStr.length ; i++ ) {
    //bug?回避のため毎回newする。
    var rgx = new RegExp(rtag);
    console.log( tagStr[i].match(rgx) );
}

コンソール:結果
["<br/>"]
["<br />"]
["<p>", "<br>", "<br>", "</p>"]
["<h1>", "</h1>"]
["<div style="vertical-align:bottom;">", "<span>", "</span>", "</div>"]
["<img src='http://www.example.com' alt='&'/>"]
["<script type='text/javascript'>", "</script>"]
["<p>", "</p>"]
["<span>", "</span>"]
["<input type='text' value='A > B' />"]
["<style type='text/css'>", "</style>"]
["<gd:name value='foo'/>"] //(x)html
最後のタグ文字列だけは(x)htmlバージョンの正規表現にのみマッチします。


もうちょっと簡単にする

//html
var rtag = /<\w+(?:\s+[^>]+)?\/?>|<\/\w+>/g;

//(x)html
var rxtag = /<\w+(?::\w+)?(?:\s+[^>]+)?\/?>|<\/\w+(?::\w+)?>/g;
HTMLに"&gt;"と書かずに">"とか書いてもちゃんと表示されちゃうワケだが、この簡易版の正規表現では許容できない。
というか、それを許すようなパターンを書こうとすると私ごときでは上記のようにパターンが長くなりすぎる。

なので、7行目の結果はこうなる。
["<input type='text' value='A >"]
が、これはそうなることが予想されていることなのでヨシとする。

まあ、ちゃんと"&gt;"と書けよ、と。

とりあえずこれでOK?



jQueryにこんなのがあった。
// Match a standalone tag
rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/
これはシングルタグにマッチさせるパターンなのだが"\1"とか使ってなかなか秀逸とか思ったが、これが"<p>"なんかにもマッチしちゃうので、使い方を工夫しないとこのままでは使えない。

0 Comments:

Sony Style(ソニースタイル)
デル株式会社

Recent Posts