use v5. 12;
use warnings;
# demo for:
# http://stackoverflow.com/questions/17039670/vertical-regex-matching-in-an-ascii-image
^ # beginning of line
( ?:
. # any character except \n
( ?= # lookahead
.*+ \n # go to next line
( \1 ?+ . ) # add a character to the 1st capturing group
.*+ \n # next line
( \2 ?+ . ) # add a character to the 2nd capturing group
)
) *? # repeat as few times as needed
X .*+ \n # X on the first line and advance to next line
\1 ?+ # if 1st capturing group is defined, use it, consuming exactly the same number of characters as on the first line
X .*+ \n # X on the 2nd line and advance to next line
\2 ?+ # if 2st capturing group is defined, use it, consuming exactly the same number of characters as on the first line
X # X on the 3rd line
/ xm;
my @maps = split /\n\n/ , <<'MAPS'; X
X
X
..X....
..X....
..X....
..X.X..
..X.X..
....X..
..X....
..X....
...X...
..X....
...X...
..X....
....X..
.X..X..
.X.....
MAPS
for ( my $i = 0 ; $i < @maps ; ++ $i ) {
my $map = $maps [ $i ] ;
my $m = $map =~ /$r/ ;
say "map $i:" ;
say "$map\n " ;
say $m ? "MATCHED:" : "no match" ;
say $& if $m ;
say "---------------" ;
}
dXNlIHY1LjEyOwp1c2Ugd2FybmluZ3M7CgojIGRlbW8gZm9yOgojIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTcwMzk2NzAvdmVydGljYWwtcmVnZXgtbWF0Y2hpbmctaW4tYW4tYXNjaWktaW1hZ2UKCgpteSAkciA9IHFyLwpeICAgICAgICAgICAgICAgICAgICAgICAgIyBiZWdpbm5pbmcgb2YgbGluZQooPzoKICAgIC4gICAgICAgICAgICAgICAgICAgICMgYW55IGNoYXJhY3RlciBleGNlcHQgXG4KICAgICg/PSAgICAgICAgICAgICAgICAgICMgbG9va2FoZWFkCiAgICAgICAgLiorXG4gICAgICAgICAgICAjIGdvIHRvIG5leHQgbGluZQogICAgICAgICggXDE/KyAuICkgICAgICAgIyBhZGQgYSBjaGFyYWN0ZXIgdG8gdGhlIDFzdCBjYXB0dXJpbmcgZ3JvdXAKICAgICAgICAuKitcbiAgICAgICAgICAgICMgbmV4dCBsaW5lCiAgICAgICAgKCBcMj8rIC4gKSAgICAgICAjIGFkZCBhIGNoYXJhY3RlciB0byB0aGUgMm5kIGNhcHR1cmluZyBncm91cAogICAgKQopKj8gICAgICAgICAgICAgICAgICAgICAgIyByZXBlYXQgYXMgZmV3IHRpbWVzIGFzIG5lZWRlZApYIC4qK1xuICAgICAgICAgICAgICAgICAgIyBYIG9uIHRoZSBmaXJzdCBsaW5lIGFuZCBhZHZhbmNlIHRvIG5leHQgbGluZQpcMT8rICAgICAgICAgICAgICAgICAgICAgIyBpZiAxc3QgY2FwdHVyaW5nIGdyb3VwIGlzIGRlZmluZWQsIHVzZSBpdCwgY29uc3VtaW5nIGV4YWN0bHkgdGhlIHNhbWUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgYXMgb24gdGhlIGZpcnN0IGxpbmUKWCAuKitcbiAgICAgICAgICAgICAgICAgICMgWCBvbiB0aGUgMm5kIGxpbmUgYW5kIGFkdmFuY2UgdG8gbmV4dCBsaW5lClwyPysgICAgICAgICAgICAgICAgICAgICAjIGlmIDJzdCBjYXB0dXJpbmcgZ3JvdXAgaXMgZGVmaW5lZCwgdXNlIGl0LCBjb25zdW1pbmcgZXhhY3RseSB0aGUgc2FtZSBudW1iZXIgb2YgY2hhcmFjdGVycyBhcyBvbiB0aGUgZmlyc3QgbGluZQpYICAgICAgICAgICAgICAgICAgICAgICAgIyBYIG9uIHRoZSAzcmQgbGluZQoveG07CgoKbXkgQG1hcHMgPSBzcGxpdCAvXG5cbi8sIDw8J01BUFMnOwpYClgKWAoKLi5YLi4uLgouLlguLi4uCi4uWC4uLi4KCi4uWC5YLi4KLi5YLlguLgouLi4uWC4uCgouLlguLi4uCi4uWC4uLi4KLi4uWC4uLgoKLi5YLi4uLgouLi5YLi4uCi4uWC4uLi4KCi4uLi5YLi4KLlguLlguLgouWC4uLi4uCk1BUFMKCgpmb3IobXkgJGkgPSAwOyAkaSA8IEBtYXBzOyArKyRpKXsKICAgIG15ICRtYXAgPSAkbWFwc1skaV07CglteSAkbSA9ICRtYXAgPX4gLyRyLzsKCXNheSAibWFwICRpOiI7CglzYXkgIiRtYXBcbiI7CgkKCXNheSAkbSA/ICJNQVRDSEVEOiI6ICJubyBtYXRjaCI7CglzYXkgJCYgaWYgJG07CgkKCXNheSAiLS0tLS0tLS0tLS0tLS0tIjsKfQo=