Peter’s blog ✴ Week 131 ✴ 20 September 2021

THE WEEKLY CHALLENGE
Consecutive pairs

The Perl Camel

Task 2

Find pairs

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.

Examples


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:
    /**/<
    /**/>

Analysis

The task description is not entirely clear, though the examples help a bit.

My approach is to make strings of the opening and closing characters and then use:

$openers =~ s|[^\Q$opens\E]||g;
$closers =~ s|[^\Q$closes\E]||g;

to remove those characters from the input string.

I hope that's what was wanted.

I am sorry that the 'Try it' feature is currently working very slowly or not at all owing to some issue with my web hosting provider.

Try it 

Try running the script with any input:



example: ()[]



example: (the cat) [sat on the mat]

Script


#!/usr/bin/perl
use strict;
use warnings;
use v5.26;

find_pairs('""[]()', '"I like (parens) and the Apple ][+" they said.');
find_pairs('**//<>', '/* This is a comment (in some languages) */ <could be a tag>');
find_pairs('{}##^!', '{note 1} #danger# ^switch off power first! #by order#');

sub find_pairs {

    my ($delimiter_pairs, $search_string, $openers, $closers, $opens, $closes);

    # copy the search string
    ($delimiter_pairs) = $_[0];
    $openers = $closers = $search_string = $_[1];

    # pick off the delimiters in pairs and make strings of the opening and closing characters
    while ($delimiter_pairs =~ m|(.)(.)|g) {
        $opens .= $1;
        $closes .= $2;
    }

    # remove all but the opening characters from $openers and similarly with $closers
    $openers =~ s|[^\Q$opens\E]||g;
    $closers =~ s|[^\Q$closes\E]||g;

    say qq[\nInput:\n   Delimiter pairs: $delimiter_pairs];
    say qq[   Search string: $search_string];
    say qq[Output:\n   $openers];
    say qq[   $closers];
}

13 lines of code

Output from script


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

Input:
   Delimiter pairs: **//<>
   Search string: /* This is a comment (in some languages) */ 
Output:
   /**/<
   /**/>

Input:
   Delimiter pairs: {}##^!
   Search string: {note 1} #danger# ^switch off power first! #by order#
Output:
   {##^##
   }##!##

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain