Skip to content

Instantly share code, notes, and snippets.

@kobachi
Last active August 29, 2015 14:05
Show Gist options
  • Save kobachi/803f259ed3c236005684 to your computer and use it in GitHub Desktop.
Save kobachi/803f259ed3c236005684 to your computer and use it in GitHub Desktop.
Extracts groups from regular expression
(function(){
var undefined;
function Group(start, end, nest){
this.start = start;
this.end = end;
this.nest = nest;
this.pattern = undefined;
}
Group.prototype.toString = function(){
return this.pattern;
}
RegExp.parseGroups = function(pattern){
var groups = [];
var groupNestStack = [];
var nest = 0;
for(var p = 0; p < pattern.length; p++){
//エスケープ
if(pattern[p] == "\\"){
p++;
continue;
}
//グループ開始
if(pattern[p] == "("){
if(typeof groupNestStack[nest] == "undefined"){
//スタック初期化
groupNestStack[nest] = [];
}
//グループ追加
var g = new Group(p, -1, nest);
groups.push(g);
groupNestStack[nest].push(g);
//ネスト増加
nest++;
continue;
}
//グループ終了
if(pattern[p] == ")"){
//後続文字列チェック
var n = p + 1;
if(n < pattern.length){
switch(pattern[n]){
case "*"://0回以上の繰り返し
case "+"://1回以上の繰り返し
case "?"://0または1回
//文字インデックスを進める
p = n;
break;
case "{":
//n~m回の繰り返し開始文字
while(n < pattern.length){
//エスケープ
if(pattern[n] == "\\"){
n += 2;
continue;
}
//n~m回の繰り返し終端文字
if(pattern[n] == "}"){
//文字インデックスを進める
p = n;
break;
}
n++;
}
break;
default:
break;
}
}
//スタックから除去
var g = groupNestStack[nest - 1].pop();
//グループ終端位置更新
g.end = p + 1;
//パターン抽出
g.pattern = pattern.substring(g.start, g.end);
//ネスト減少
nest--;
continue;
}
}
//グループインデックスのソート
groups.sort(function(g1, g2){
if(g1.nest == g2.nest){
return g1.start - g2.start
}
return g1.nest - g2.nest;
});
//参照しないグループを取り除く
for(var i = groups.length - 1; 0 <= i; i--){
if(groups[i].pattern.indexOf("(?:") == 0){
groups.splice(i, 1);
}
}
return groups;
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment