views:

112

answers:

3

OK, I got a weird one that I've been jamming on for awhile (fri afternoon mind does not work I guess).

Does anyone know of a away to parse a string and remove all of the text inside parens without removing the parens themselves...but with deleting parens found inside.

ie.

myString = "this is my string (though (I) need (help) fixing it)"

after running it through what I want it would look like:

myString = "this is my string ()"

very important to keep those two parens there.

+6  A: 

You need to escape the parentheses to prevent them from starting a capture group. The pattern \(.+\) match the longest substring that starts with a ( and ends with a ). That will gobble up everything up to the last ) including any intervening parentheses. Finally, we replace that string with one containing just ():

#!/usr/bin/perl

use strict; use warnings;

my $s = "this is my string (though (I) need (help) fixing it)";

$s =~ s{\(.+\)}{()};

print "$s\n";
Sinan Ünür
This works as long as there's only one top level set of parentheses. Otherwise, a string like "this is my (string (that)) I (need help fixing)" would become "this is my ()" instead of "this is my () I ()"
bobDevil
+10  A: 

The module Regexp::Common deals with more than 1 top level of parentheses.

use strict;
use warnings;
use Regexp::Common qw/balanced/;

my @strings = (
    '111(22(33)44)55',
    'a(b(c(d)(e))f)g(h)((i)j)',
    'this is my string (though (I) need (help) fixing it)',
);

s/$RE{balanced}{-parens=>'()'}/()/g for @strings;

print "$_\n" for @strings;

Output:

111()55
a()g()()
this is my string ()
Chris Charley
Woah, Cool! Regexp::Common surprises me regularly with its verbose set of regexen...
Robert P
Sinan, thanks for the clarification in the code.
Chris Charley
I'm not surprised that it can be done in one line of Perl, but I am surprised that it is readable!
dreamlax
+2  A: 

If you want to use Regular Expressions without using Regexp::Common. Look at the "Look Around" Feature. It was introduced with Perl 5. You can read more about "Look Ahead" and "Look Behind" at regular-expressions.info. There is also a section on "Look Around" in the "Mastering Regular Expressions" book. Look on page 59.

#!/usr/bin/env perl

use Modern::Perl;

my $string = 'this is my (string (that)) I (need help fixing)';

$string =~ s/(?<=\()[^)]+[^(]+(?=\))//g;

say $string;
J.J.