トップページに戻る
次の正規表現パズルへ
前の正規表現パズルへ
7-6 括弧に囲まれたaを検索
正規表現パズル
行頭直後の括弧に囲まれたaを検索する。
検索前
検索後
対象データ
(a)
((a))
(((a)))
((((a))))
a
((a)
(((a)
(((a))
(((((a)))
正規表現
^(?=\()(?<r1>\(\g<r1>\)|a)
別解
^(?<r1>\((a|\g<r1>)\))
解説
まず先読みを除いた下記の正規表現
^(?<r1>\(\g<r1>\)|a)
の再帰について考えて、
再帰レベル0なら ^a
再帰レベル1なら ^(a)
再帰レベル2なら ^((a))
再帰レベル3なら ^(((a)))
再帰レベル4なら ^((((a))))
以下略
といった感じで正規表現を考えると分かりやすいでしょう。
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
PL/SQLやC言語の再帰呼び出しと同じく、
リテラルな戻り値がないと
再帰呼び出しが終わらなくなるのと同じ理屈が
田中哲スペシャルの再帰呼び出しでも成立してます。
declare
function kaijyo(hikiSuu pls_Integer) return pls_Integer is
begin
if hikiSuu = 1 then
return 1;
else
return hikiSuu * kaijyo(hikiSuu-1);
end if;
end kaijyo;
begin
DBMS_Output.Put_Line('5の階乗=' || to_char(kaijyo(5)));
DBMS_Output.Put_Line('8の階乗=' || to_char(kaijyo(8)));
end;
/
5の階乗=120
8の階乗=40320
#Rubyでのソースと実行結果
ConstRegex = Regexp.new('^(?<r1>\((a|\g<r1>)\))')
hairetu = Array.new
hairetu.push('(a)')
hairetu.push('((a))')
hairetu.push('(((a)))')
hairetu.push('((((a))))')
hairetu.push('a')
hairetu.push('((a)')
hairetu.push('(((a)')
hairetu.push('(((a))')
hairetu.push('(((((a)))')
puts "Pattern #{ConstRegex.source}"
for i in (0..hairetu.length-1)
willOut = "Line#{i+1} #{hairetu[i]} "
work = ConstRegex.match(hairetu[i]).to_a[0]
if work then
willOut += 'matchs ' + work
else
willOut += 'no match'
end
puts willOut
end
#実行結果
Pattern ^(?=\()(?<r1>\(\g<r1>\)|a)
Line1 (a) matchs (a)
Line2 ((a)) matchs ((a))
Line3 (((a))) matchs (((a)))
Line4 ((((a)))) matchs ((((a))))
Line5 a no match
Line6 ((a) no match
Line7 (((a) no match
Line8 (((a)) no match
Line9 (((((a))) no match