JavaScriptの正規表現で当てはまるすべてのパターンを抜き出す

例えば、liタグの中の要素を1つずつ抜き出して配列に入れることを想定する。

var str = "<li>test</li><li>test2</li><li>test3</li><li>test4</li>";
str.match(/<li>(.*)<\/li>/);

実行結果

Array [ "<li>test</li><li>test2</li><li>test3</li><li>test4</li>", "test</li><li>test2</li><li>test3</li><li>test4" ]

この場合だと文字列中で、最初にマッチしてから、最後にマッチするまでを括っている。
第0要素には、マッチした文字列が、第1要素には、()から抜き出した文字列が入る。

var str = "<li>test</li><li>test2</li><li>test3</li><li>test4</li>";
str.match(/<li>(.*?)<\/li>/);

実行結果

Array [ "<li>test</li>", "test" ]

これだと最初にマッチした部分しか取得できない。


そこで、当てはまるすべてをチェックするgオプションをつけてみると、

var str = "<li>test</li><li>test2</li><li>test3</li><li>test4</li>";
str.match(/<li>(.*?)<\/li>/g);

実行結果

Array [ "<li>test</li>", "<li>test2</li>", "<li>test3</li>", "<li>test4</li>" ]

このように、当てはまった各第0要素が配列に入って、liタグが邪魔です。
どうすればよいのか調べたところ答えがありました。

var a = [];
var str = "<li>test</li><li>test2</li><li>test3</li><li>test4</li>";
var r = /<li>(.*?)<\/li>/g;
while((m = r.exec(str)) != null){
         a.push(m[1]);
}

実行結果

Array [ "test", "test2", "test3", "test4" ]


参考サイト

正規表現の(.*?)と(.*)の違い - Qiita
.exec() | JavaScript 日本語リファレンス | js STUDIO
javascript - JavaScript正規表現でマッチした全ての値を配列で取得する - スタック・オーバーフロー
JavaScriptの正規表現は4つのパターンで理解できる! | 侍エンジニア塾ブログ | プログラミング入門者向け学習情報サイト
【JavaScriptの正規表現】10分で分かる基本パターン | TECH::NOTE | プログラミングをはじめる全ての人に