トップページに戻る    次の正規表現パズルへ    前の正規表現パズルへ

7-12 回文な行を検索

正規表現パズル

回文な行を検索する。

検索前


検索後


対象データ

abc
abbb
ddd
dddd
abccba
abcba
abcdedcba
11
111
1111
tomato
racecar
wasitabarorabatisaw
abcdeffedcba
abcdefghijk
abcdefedcba


正規表現

^(?<rec>(?<cap>.)(\g<rec>|.)?\k<cap+0>)$


解説

この正規表現なら、
再帰Level0の正規表現
再帰Level1の正規表現
再帰Level2の正規表現
再帰Level3の正規表現
を脳内でイメージするのがよさそうです。

文字数が固定なら固定位置で後方参照を使えばいいです。
3-33 文字数固定で回文な行を検索

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
X
Y
などの1文字のみの行も回文だろうということで
^(?<rec>(?<cap>.)(\g<rec>|.)?\k<cap+0>)$
を
^(?<rec>(?<cap>.)(\g<rec>|.)?\k<cap+0>)$|^.$
にしたら
サクラエディタ1.6.2.0と
ruby 1.9.0 (2008-06-20 revision 17482) [i386-mswin32]
で結果が異なりました。
rubyが正しい結果だと思いますが


#Rubyでのソースと実行結果

wStr = '^(?<rec>(?<cap>.)(\g<rec>|.)?\k<cap+0>)$'
ConstRegex = Regexp.new(wStr)
hairetu = Array.new
hairetu.push('abc')
hairetu.push('abbb')
hairetu.push('ddd')
hairetu.push('dddd')
hairetu.push('abccba')
hairetu.push('abcba')
hairetu.push('abcdedcba')
hairetu.push('11')
hairetu.push('111')
hairetu.push('1111')
hairetu.push('tomato')
hairetu.push('racecar')
hairetu.push('wasitabarorabatisaw')
hairetu.push('abcdeffedcba')
hairetu.push('abcdefghijk')
hairetu.push('abcdefedcba')

puts "Pattern #{ConstRegex.source}"
for i in (0..hairetu.length-1)
    willOut = sprintf("Line%02d",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 ^(?<rec>(?<cap>.)(\g<rec>|.)?\k<cap+0>)$
Line01 abc no match
Line02 abbb no match
Line03 ddd matchs ddd
Line04 dddd matchs dddd
Line05 abccba matchs abccba
Line06 abcba matchs abcba
Line07 abcdedcba matchs abcdedcba
Line08 11 matchs 11
Line09 111 matchs 111
Line10 1111 matchs 1111
Line11 tomato no match
Line12 racecar matchs racecar
Line13 wasitabarorabatisaw matchs wasitabarorabatisaw
Line14 abcdeffedcba matchs abcdeffedcba
Line15 abcdefghijk no match
Line16 abcdefedcba matchs abcdefedcba