# Capitalizing on Regular Expressions **Challenge 330 solutions in Perl by Matthias Muth** ## Task 1: Clear Digits > You are given a string containing only lower case English letters and digits.
> Write a script to remove all digits by removing the first digit and the closest non-digit character to its left. > > **Example 1** > > ```text > Input: $str = "cab12" > Output: "c" > > Round 1: remove "1" then "b" => "ca2" > Round 2: remove "2" then "a" => "c" >``` > >**Example 2** > >```text > Input: $str = "xy99" > Output: "" > >Round 1: remove "9" then "y" => "x9" > Round 2: remove "9" then "x" => "" > ``` > > **Example 3** > > ```text >Input: $str = "pa1erl" > Output: "perl" > ``` Seems we need to remove pairs of non-digit and digit characters, repeatedly. Not a big deal for regular expressions.
A substitution operator will do the removing, and as the result of that substitution indicates whether a replacement was found or not, it can serve as a loop condition, too. As there is nothing else to be done, the loop will consist of the loop condition only, with an empty body. I like to put a comment into empty loops to make it obvious for the reader. That ```perl use v5.36; sub clear_digits( $str ) { while ( $str =~ s/[a-z]\d// ) { # Everything is in the loop condition. } return $str; } ``` ## Task 2: Title Capital > You are given a string made up of one or more words separated by a single space.
> Write a script to capitalise the given title. If the word length is 1 or 2 then convert the word to lowercase otherwise make the first character uppercase and remaining lowercase. > > **Example 1** > > ```text > Input: $str = "PERL IS gREAT" > Output: "Perl is Great" > ``` > > **Example 2** > > ```text > Input: $str = "THE weekly challenge" > Output: "The Weekly Challenge" > ``` > > **Example 3** > > ```text > Input: $str = "YoU ARE A stAR" > Output: "You Are a Star" > ``` The second task, too, is easily solved with a regular expression. Here, I use three capture buffers: * one for the first letter, which might have to be put into lower or uppercase depending on the length of the word: `(\w)` * one for a possible second character: `(\w?)` * and one for the (possibly empty) rest of the word, from the third character to the end: `(\w*)`. The third capture has a special role:
If it is empty, the whole word is only one or two characters long, and the first letter needs to be lowercase.
If it is non-empty, we need to uppercase the first letter. The second and third captures will always be lowercased for the result. My whole solution consists of a single substitution, with a `/e` option to evaluate the substitution part as an expression, a `/g` option to repeat the substitution as often as possible, and a `/r` option to return the resulting final string instead of the number of substitutions done.
When I use the `/e` option, I put the expression into a pair of curly brackets, to give an optical hint that this is 'code' to be evaluated. I then use angle brackets for the pattern part. So here we go: ```perl use v5.36; sub title_capital( $str ) { return $str =~ s<(\w)(\w?)(\w*)>{ ( $3 ? uc $1 : lc $1 ) . lc "$2$3" }egr; } ``` #### **Thank you for the challenge!**