# Perl Weekly Challenge 131: Find Pairs

by Abigail

## Challenge

You are given a string of delimiter pairs and a string to search.

Write a script to return two strings, the first with any characters matching the “opening character” set, the second with any matching the “closing character” set.

### Example 1

Input:
Delimiter pairs: ""[]()
Search String: "I like (parens) and the Apple ][+" they said.

Output:
"(["
")]"


### Example 2

Input:
Delimiter pairs: **//<>
Search String: /* This is a comment (in some languages) */ <could be a tag>

Output:
/**/<
/**/>


## Discussion

What a strange way to phrase the exercise. The entire "delimiter pairs" is a red herring. We are not asked to do anything with delimiting pairs. This is clear from both examples. Take for instance the first example; the first delimiting pair using " for both the opening delimiter and the closing delimiter. And the string to search in, uses a single pair of double quotes as delimiting pair. Yet, the pair appears in both the output strings.

So, basically we are given a string, and two sets of characters we need to extract from the string, and for some perverse reason, the two sets of characters are interleaved. Weird.

### Perl

First, we read the input. First line of input are the interleaved sets of characters to extract - second line of input is the string we want to search:

chomp (my $chars = <>);$_ = <>;


We remove the newline from the first line we read; there is no need to bother to remove it from the second line.

We now extract the characters from $char in the odd and even positions, giving us two sets of characters. We do this by removing the characters on the even and odd positions from $char; and since we use the /r modifier, $char itself is unmodified, and the modified string is returned. We also escape any slashes in the sets (for reasons which will soon be clear). my$odds = $chars =~ s/(.)./$1/gr =~ s!([/\\])!\\$1!r; my$even = $chars =~ s/.(.)/$1/gr =~ s!([/\\])!\\$1!r;  We can now use y///dc to remove any characters which aren't in the sets we need to extract — this leaves use with the characters we need to extract. Since y/// doesn't do interpolation, we use eval. And this explains why we need to escape any slashes above. say eval "y/$odds//dcr";
say eval "y/\$even//dcr";


Find the full program on GitHub.