Last active
August 29, 2015 13:57
-
-
Save znz/9835956 to your computer and use it in GitHub Desktop.
Ruby/Rails勉強会@関西 60th #rubykansai のプレゼン用に作成した正規表現(ごく一部)の動作をステップ表示するアプリ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
source "https://rubygems.org" | |
ruby "2.1.1" | |
gem "sinatra" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
GEM | |
remote: https://rubygems.org/ | |
specs: | |
rack (1.5.2) | |
rack-protection (1.5.2) | |
rack | |
sinatra (1.4.4) | |
rack (~> 1.4) | |
rack-protection (~> 1.4) | |
tilt (~> 1.3, >= 1.3.4) | |
tilt (1.4.1) | |
PLATFORMS | |
ruby | |
DEPENDENCIES | |
sinatra |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
web: bundle exec ruby regexp-201403.rb -p $PORT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# -*- coding: utf-8 -*- | |
require 'sinatra' | |
def make_link(re, str) | |
require 'erb' | |
%Q[<li><a href="/#{URI.encode_www_form_component(re)}/#{URI.encode_www_form_component(str)}/0">/#{ERB::Util.h(re)}/ =~ "#{ERB::Util.h(str)}"</a></li>] | |
end | |
example = [ | |
make_link("abc", "abracadabra"), | |
make_link("ada", "abracadabra"), | |
make_link("a(?=br)a", "abracadabra"), | |
make_link("a(?=.r)b.a", "abracadabra"), | |
make_link("foo(?=bar)", "foobar"), | |
make_link("(?=foo)bar", "foobar"), | |
] | |
get '/' do | |
example.join('') | |
end | |
def step(state) | |
STDERR.puts state.inspect | |
return state if state[:step] <= 0 | |
reg_range = state[:reg_range] | |
str_range = state[:str_range] | |
if state[:reg][reg_range.end, 3] == '(?=' | |
state[:outer_range] = { | |
reg_range: reg_range, | |
str_range: str_range, | |
} | |
state[:reg_range] = reg_range.end+3...reg_range.end+3 | |
state[:str_range] = str_range.end...str_range.end | |
elsif state[:reg][reg_range.end] == ')' && state[:outer_range] | |
state[:reg_range] = reg_range.end+1...reg_range.end+1 | |
state[:str_range] = state[:outer_range][:str_range].end...state[:outer_range][:str_range].end | |
elsif state[:reg][reg_range.end] == '.' | |
state[:reg_range] = reg_range.begin...reg_range.end+1 | |
state[:str_range] = str_range.begin...str_range.end+1 | |
elsif state[:reg][reg_range.end] == state[:str][str_range.end] | |
state[:reg_range] = reg_range.begin...reg_range.end+1 | |
state[:str_range] = str_range.begin...str_range.end+1 | |
elsif state[:finished] | |
state[:reg_range] = 0...0 | |
state[:str_range] = str_range.begin+1...str_range.begin+1 | |
state[:finished] = false | |
else | |
if state[:reg].length == reg_range.end | |
state[:finished] = :matched | |
else | |
state[:finished] = :failed | |
end | |
end | |
state[:step] -= 1 | |
step(state) | |
end | |
get '/:reg/:str/:step' do | |
reg = params[:reg] | |
str = params[:str] | |
n = params[:step].to_i | |
result = step(reg: reg, str: str, step: n, reg_range: 0...0, str_range: 0...0, finished: false) | |
reg_range = result[:reg_range] | |
str_range = result[:str_range] | |
finished = result[:finished] | |
case finished | |
when :failed | |
reg[reg_range.end, 1] &&= '<span class="failed">' + reg[reg_range.end, 1] + '</span>' | |
str[str_range.end, 1] &&= '<span class="failed">' + str[str_range.end, 1] + '</span>' | |
end | |
reg[reg_range] &&= '<span class="reg-step">' + reg[reg_range] + '</span>' | |
if str[str_range] | |
str[str_range] &&= '<span class="str-step">' + str[str_range] + '</span>' | |
else | |
match_failed = true | |
end | |
[ | |
%Q[<style type="text/css">.failed{border:5px solid red} .reg-step{border:5px solid green} .str-step{border:5px solid blue}</style>], | |
%Q[<p style="font-size:128px">/#{reg}/ =~ "#{str}"</p>], | |
finished == :matched ? %Q[<p>matched</p>] : "", | |
match_failed ? %Q[<p>failed</p>] : "", | |
%Q[<p><a href="#{n-1}">prev</a> <a href="#{n+1}">next</a></p>], | |
*example, | |
].join("") | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment