Schemeの数値リテラルにマッチする正規表現
3839bytes.もっと短くしたいなぁ.見辛いので適当に改行を挿入.
/(?:(?:(?:#b)(?:(?:#[ei])?)|(?:(?:#[ei])?)(?:#b))(?:(?:(?:(?:[+-])?)(?:(?:(?:[01 ])+#*)|(?:(?:(?:[01])+#*)\/(?:(?:[01])+#*))|(?:(?!))))|(?:(?:(?:(?:[+-])?)(?:(?: (?:[01])+#*)|(?:(?:(?:[01])+#*)\/(?:(?:[01])+#*))|(?:(?!))))@(?:(?:(?:[+-])?)(?: (?:(?:[01])+#*)|(?:(?:(?:[01])+#*)\/(?:(?:[01])+#*))|(?:(?!)))))|(?:(?:(?:(?:[+- ])?)(?:(?:(?:[01])+#*)|(?:(?:(?:[01])+#*)\/(?:(?:[01])+#*))|(?:(?!))))[+\-](?:(? :(?:[01])+#*)|(?:(?:(?:[01])+#*)\/(?:(?:[01])+#*))|(?:(?!)))?i)|(?:[+\-](?:(?:(? :[01])+#*)|(?:(?:(?:[01])+#*)\/(?:(?:[01])+#*))|(?:(?!)))?i)))|(?:(?:(?:#o)(?:(? :#[ei])?)|(?:(?:#[ei])?)(?:#o))(?:(?:(?:(?:[+-])?)(?:(?:(?:[0-7])+#*)|(?:(?:(?:[ 0-7])+#*)\/(?:(?:[0-7])+#*))|(?:(?!))))|(?:(?:(?:(?:[+-])?)(?:(?:(?:[0-7])+#*)|( ?:(?:(?:[0-7])+#*)\/(?:(?:[0-7])+#*))|(?:(?!))))@(?:(?:(?:[+-])?)(?:(?:(?:[0-7]) +#*)|(?:(?:(?:[0-7])+#*)\/(?:(?:[0-7])+#*))|(?:(?!)))))|(?:(?:(?:(?:[+-])?)(?:(? :(?:[0-7])+#*)|(?:(?:(?:[0-7])+#*)\/(?:(?:[0-7])+#*))|(?:(?!))))[+\-](?:(?:(?:[0 -7])+#*)|(?:(?:(?:[0-7])+#*)\/(?:(?:[0-7])+#*))|(?:(?!)))?i)|(?:[+\-](?:(?:(?:[0 -7])+#*)|(?:(?:(?:[0-7])+#*)\/(?:(?:[0-7])+#*))|(?:(?!)))?i)))|(?:(?:(?:(?:#d)?) (?:(?:#[ei])?)|(?:(?:#[ei])?)(?:(?:#d)?))(?:(?:(?:(?:[+-])?)(?:(?:(?:[0-9])+#*)| (?:(?:(?:[0-9])+#*)\/(?:(?:[0-9])+#*))|(?:(?:(?:(?:[0-9])+#*)(?:(?:(?:[esfdl])(? :(?:[+-])?)(?:[0-9])+)?))|(?:\.(?:[0-9])+#*(?:(?:(?:[esfdl])(?:(?:[+-])?)(?:[0-9 ])+)?))|(?:(?:[0-9])+\.(?:[0-9])*#*(?:(?:(?:[esfdl])(?:(?:[+-])?)(?:[0-9])+)?))| (?:\.(?:[0-9])+#+\.#*(?:(?:(?:[esfdl])(?:(?:[+-])?)(?:[0-9])+)?)))))|(?:(?:(?:(? :[+-])?)(?:(?:(?:[0-9])+#*)|(?:(?:(?:[0-9])+#*)\/(?:(?:[0-9])+#*))|(?:(?:(?:(?:[ 0-9])+#*)(?:(?:(?:[esfdl])(?:(?:[+-])?)(?:[0-9])+)?))|(?:\.(?:[0-9])+#*(?:(?:(?: [esfdl])(?:(?:[+-])?)(?:[0-9])+)?))|(?:(?:[0-9])+\.(?:[0-9])*#*(?:(?:(?:[esfdl]) (?:(?:[+-])?)(?:[0-9])+)?))|(?:\.(?:[0-9])+#+\.#*(?:(?:(?:[esfdl])(?:(?:[+-])?)( ?:[0-9])+)?)))))@(?:(?:(?:[+-])?)(?:(?:(?:[0-9])+#*)|(?:(?:(?:[0-9])+#*)\/(?:(?: [0-9])+#*))|(?:(?:(?:(?:[0-9])+#*)(?:(?:(?:[esfdl])(?:(?:[+-])?)(?:[0-9])+)?))|( ?:\.(?:[0-9])+#*(?:(?:(?:[esfdl])(?:(?:[+-])?)(?:[0-9])+)?))|(?:(?:[0-9])+\.(?:[ 0-9])*#*(?:(?:(?:[esfdl])(?:(?:[+-])?)(?:[0-9])+)?))|(?:\.(?:[0-9])+#+\.#*(?:(?: (?:[esfdl])(?:(?:[+-])?)(?:[0-9])+)?))))))|(?:(?:(?:(?:[+-])?)(?:(?:(?:[0-9])+#* )|(?:(?:(?:[0-9])+#*)\/(?:(?:[0-9])+#*))|(?:(?:(?:(?:[0-9])+#*)(?:(?:(?:[esfdl]) (?:(?:[+-])?)(?:[0-9])+)?))|(?:\.(?:[0-9])+#*(?:(?:(?:[esfdl])(?:(?:[+-])?)(?:[0 -9])+)?))|(?:(?:[0-9])+\.(?:[0-9])*#*(?:(?:(?:[esfdl])(?:(?:[+-])?)(?:[0-9])+)?) )|(?:\.(?:[0-9])+#+\.#*(?:(?:(?:[esfdl])(?:(?:[+-])?)(?:[0-9])+)?)))))[+\-](?:(? :(?:[0-9])+#*)|(?:(?:(?:[0-9])+#*)\/(?:(?:[0-9])+#*))|(?:(?:(?:(?:[0-9])+#*)(?:( ?:(?:[esfdl])(?:(?:[+-])?)(?:[0-9])+)?))|(?:\.(?:[0-9])+#*(?:(?:(?:[esfdl])(?:(? :[+-])?)(?:[0-9])+)?))|(?:(?:[0-9])+\.(?:[0-9])*#*(?:(?:(?:[esfdl])(?:(?:[+-])?) (?:[0-9])+)?))|(?:\.(?:[0-9])+#+\.#*(?:(?:(?:[esfdl])(?:(?:[+-])?)(?:[0-9])+)?)) ))?i)|(?:[+\-](?:(?:(?:[0-9])+#*)|(?:(?:(?:[0-9])+#*)\/(?:(?:[0-9])+#*))|(?:(?:( ?:(?:[0-9])+#*)(?:(?:(?:[esfdl])(?:(?:[+-])?)(?:[0-9])+)?))|(?:\.(?:[0-9])+#*(?: (?:(?:[esfdl])(?:(?:[+-])?)(?:[0-9])+)?))|(?:(?:[0-9])+\.(?:[0-9])*#*(?:(?:(?:[e sfdl])(?:(?:[+-])?)(?:[0-9])+)?))|(?:\.(?:[0-9])+#+\.#*(?:(?:(?:[esfdl])(?:(?:[+ -])?)(?:[0-9])+)?))))?i)))|(?:(?:(?:#x)(?:(?:#[ei])?)|(?:(?:#[ei])?)(?:#x))(?:(? :(?:(?:[+-])?)(?:(?:(?:[0-9a-f])+#*)|(?:(?:(?:[0-9a-f])+#*)\/(?:(?:[0-9a-f])+#*) )|(?:(?!))))|(?:(?:(?:(?:[+-])?)(?:(?:(?:[0-9a-f])+#*)|(?:(?:(?:[0-9a-f])+#*)\/( ?:(?:[0-9a-f])+#*))|(?:(?!))))@(?:(?:(?:[+-])?)(?:(?:(?:[0-9a-f])+#*)|(?:(?:(?:[ 0-9a-f])+#*)\/(?:(?:[0-9a-f])+#*))|(?:(?!)))))|(?:(?:(?:(?:[+-])?)(?:(?:(?:[0-9a -f])+#*)|(?:(?:(?:[0-9a-f])+#*)\/(?:(?:[0-9a-f])+#*))|(?:(?!))))[+\-](?:(?:(?:[0 -9a-f])+#*)|(?:(?:(?:[0-9a-f])+#*)\/(?:(?:[0-9a-f])+#*))|(?:(?!)))?i)|(?:[+\-](? :(?:(?:[0-9a-f])+#*)|(?:(?:(?:[0-9a-f])+#*)\/(?:(?:[0-9a-f])+#*))|(?:(?!)))?i))) /i
テスト結果.
accept: 0 accept: 10 accept: 256 accept: +10 accept: -10 accept: 10.0 accept: .0 accept: 0. accept: 10e3 accept: 10e+2 accept: 10e-2 accept: 10s+3 accept: 10f+3 accept: 10d+3 accept: 10l+3 accept: 13+3i accept: +i accept: -i accept: 13.0+3.0i accept: +.1i accept: .1+i accept: #d256 accept: #xff accept: #b1010 accept: #o256 accept: #e256 accept: #i256 accept: #e#xff accept: #x#eff accept: 3/4 accept: #i3/4 accept: #e3/4 accept: #i.75 accept: #e.75 accept: 1@1 accept: 1.2@3.4 reject: #xff.ff reject: 10e+i reject: #b2 reject: #o9 reject: f reject: + reject: #f
多分いけてる.こんなに長い正規表現を書いたのは初めてだなぁ.手書きじゃないけど.強欲マッチにできるところは強欲マッチにしないと,遅いかもしれない.
上の正規表現を生成するコード.
exponent_marker = /[esfdl]/ sign = /(?:[+-])?/ exactness = /(?:#[ei])?/ radix_ary = /#b/, /#o/, /(?:#d)?/, /#x/ digit = /[0-9]/ digit_ary = /[01]/, /[0-7]/, digit, /[0-9a-f]/ suffix = /(?:#{exponent_marker}#{sign}#{digit}+)?/ ary = Array.new(4) {|i| r_prefix = /#{radix_ary[i]}#{exactness}|#{exactness}#{radix_ary[i]}/ r_nosign_integer = /#{digit_ary[i]}+#*/ r_float = if 2 == i Regexp.union(/#{r_nosign_integer}#{suffix}/, /\.#{digit}+#*#{suffix}/, /#{digit}+\.#{digit}*#*#{suffix}/, /\.#{digit}+#+\.#*#{suffix}/) else /(?!)/ end r_nosign_real = Regexp.union(r_nosign_integer, /#{r_nosign_integer}\/#{r_nosign_integer}/, r_float) r_real = /#{sign}#{r_nosign_real}/ r_complex = Regexp.union(r_real, /#{r_real}@#{r_real}/, /#{r_real}[+\-]#{r_nosign_real}?i/, /[+\-]#{r_nosign_real}?i/) r_number = /#{r_prefix}#{r_complex}/ } re = Regexp.new(Regexp.union(ary).source.gsub(/-mix/, ""), Regexp::IGNORECASE)